python 的函數、值傳遞、和作用域(例子)

1.python的函數格式

        def FuncName([arg1,arg2,..]):
                func_suite

        def: def是函數的關鍵字
        FuncName: 實際也是變量,它指向函數對象,在函數定義時被賦值,根據習慣,這裏我們成爲函數名
        ():()是函數運算符,引用函數時,用函數名+()引用,如: FuncName()
        [arg1,arg2,..]: 這個是函數體的參數,當爲空時,我們稱這個函數爲無參函數,相對應的就是有參函數,python的參數傳遞很強大,可以是位置參數一一對應,也可以默認參數賦值,還可以傳遞字典等
        ":" : python的語句都必須以 : 結尾
        func_suite: 這個是函數體的內容,可以用"pass"進行佔位,還可以嵌套函數等

需要注意的是,每個函數結束後都必須返回值,如果沒有用return關鍵字明確指明,那麼默認返回None

例子:

In [2]: def hello():
...: print "hello"
...:

In [3]: a=hello()
hello

In [4]: print a
None

2.參數傳遞

<1>普通的從左往右匹配的參數傳遞

 def f1(x,y):
     print "x:%d y:%d" %(x,y)

In [38]: m=1

In [39]: n=2

In [40]: f1(m,n)
x:1 y:2

In [41]: f1(n,m)
x:2 y:1

這種方式傳參個數必須匹配,否則報錯

<2>設置默認參數

In [42]: def f2(x=1,y):
    ...:     print "x:%d y:%d" %(x,y)
  File "<ipython-input-42-52965f3ab864>", line 1
    def f2(x=1,y):
SyntaxError: non-default argument follows default argument

In [43]: def f2(y,x=1):
    ...:     print "x:%d y:%d" %(x,y)
In [45]: n=99

In [46]: m=6

In [47]: f2(n)
x:1 y:99

In [48]: f2(n,m)
x:6 y:99

(1)默認參數要寫在位置參數後面,否則報錯
(2)傳遞參數時,可以不傳遞默認有值的參數,但是當傳遞了對應參數,默認值會被覆蓋掉

<3>1個'*',傳遞任意個數參數(非鍵值對),函數收集爲列表

In [53]: def f3(x,*y):
...:     print x,y
...:       

In [54]: n=1;m=2

In [55]: f3(n,m,4,5,6)
1 (2, 4, 5, 6)

帶*的參數也要放在位置參數後面,位置參數匹配完後,剩下的纔會收集爲列表並賦值給y這個變量

<4>2個'*',傳遞任意個鍵值對參數,收集爲字典

In [85]: def f4(x,**y):
    ...:     print x,y
    ...:     

In [86]: f4(1,n=2,a=4,b=2)
1 {'a': 4, 'b': 2, 'n': 2}

3.python的作用域(LEGB),參考:https://segmentfault.com/a/1190000000640834
簡而言之,LEGB 代表名字查找順序: locals -> enclosing function -> globals -> builtins

    locals 是函數內的名字空間,包括局部變量和形參
    enclosing 外部嵌套函數的名字空間(閉包中常見)
    globals 全局變量,函數定義所在模塊的名字空間
    builtins 內置模塊的名字空間

所以,在 Python 中檢索一個變量的時候,優先回到 locals 裏面來檢索,檢索不到的情況下會檢索 enclosing ,enclosing 沒有則到 globals 全局變量裏面檢索,最後是到 builtins 裏面來檢索。

例子:

[root@cqhdtest python_learn]# ./getvalue.py 
Ex Gy Ez
Lx Gy Ez
[root@cqhdtest python_learn]# cat getvalue.py 
#!/usr/local/anaconda2/bin/python
x='Gx'
y='Gy'
z='Gz'
def f1(x,y,z):
    x='Ex'
    z='Ez'
    print x,y,z
    def f2(x,y,z):
    x='Lx'
    print x,y,z
    f2(x,y,z)
f1(x,y,z)

當調用f1函數時,此時f1中的print語句會去尋找x,y,z變量的值,它從當前作用域開始找,x,z都在本域有值,所以x='Ex',z='Ez',y沒有值,所以它向外去globals作用域找,發現y='Gy',所以第一行輸出爲"Ex Gy Ez",程序繼續執行,調用f2函數,f2的print也查找x,y,z的變量的值,首先在local域找,發現x="Lx",y在local找不到,於是去enclosing域找,發現也沒有,於是找Global域,所以y='Gy',z同理,在enclosing域找到了,便停止搜索,於是z='Ez',所以第二行輸出爲"Lx Gy Ez"

如果我們想在函數內對全局變量進行修改,則可以使用global關鍵字

    global:告訴函數,使用全局變量作爲當前變量

例子:

[root@cqhdtest python_learn]# ./global.py 
Gx
Ex
[root@cqhdtest python_learn]# cat global.py 
#!/usr/local/anaconda2/bin/python
x='Gx'
def f1():
    x='Ex'
def f2():
    global x
    x='Ex'
f1()
print x
f2()
print x

函數f1中的x是本地變量,當f1執行完後x的值也被銷燬
函數f2中的x使用全局變量,所以當x被改變後,print的值也變了
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章