一、做用域 :函數外的變量的做用域爲全局做用域(命名空間對應全局命名空間),函數體內的變量(未用global聲明)的做用域爲內部做用域(對應局部命名空間);函數體內的變量稱爲局部變量閉包
>>> x = 1 ###x的做用域爲全局做用域,對應全局命名空間函數
>>> def foo():
x = 42 ###x的做用域爲局部做用域 ,對應局部命名空間,具體的做用域只在函數體內;局部命名空間中的x指向42
return xspa
>>> x
1
>>> foo() ###調用foo函數的時候,局部命名空間就被建立,僅做用於函數內代碼塊
42
>>> x ###調用的全局做用域(全局命名空間)中的x指向的值,因此x=1
1code
二、Shadowing屏蔽的問題;若是函數體內的局部變量和全局變量的名字相同,在函數體內引用全局變量的話,局部變量會把全局變量屏蔽掉blog
>>> def combine(parameter):
external = 'berry'
print(parameter+external)ip
>>> external = 'Sunshine'
>>> #想生成'parameter+'Sunshine''作用域
>>> combine('you are my ')
you are my berry ###這個結果並非咱們期待的結果,由於局部變量和全局變量的名字同樣,因此局部變量把全局變量屏蔽了io
三、globals()函數,無參數,將獲取全局變量的字典類型,使用方法 globals()['全局變量名'] 返回全局變量對應的值;修改上面的函數function
>>> def combine(parameter):
external = 'berry'
print(parameter+globals()['external'])class
>>> external = 'Sunshine'
>>> combine('you are my ')
you are my Sunshine
四、函數內從新綁定全局變量(指向新的內容),若是函數有必要改變全局變量,使用global 變量名;用global聲明 函數體內的變量爲全局變量
>>> x = 1
>>> def change_global():
global x
x = x+1
>>> change_global()
>>> x
2
五、嵌套做用域,一個函數內嵌套了另外一個函數,外層函數返回內層函數(內層函數未被調用只是返回);內層函數是能夠訪問外層函數的變量的,這個就叫嵌套做用域;
例子:
>>> def multiplier(factor):
def multiplyByFactor(number):
return(number*factor)####外層函數multiplier的變量factor,被內層函數multiplyByFactor引用了
return multiplyByFactor###外層函數返回內層函數
相似multiplyByFactor函數,存儲於一個封閉的做用域的行爲叫作閉包(由於它引用的變量都在函數體內或者外層函數內,若是factor爲全局變量,則它就不是閉包)
查看一個函數是不是閉包用:函數.__closure__
>>> def multiplier(factor):
def multiplyByFactor(number):
return(number*factor)
print(multiplyByFactor.__closure__)###雙下劃線
return multiplyByFactor
>>> multiplier(2)
(<cell at 0x000001A961B4AEB8: int object at 0x00007FFE82BBE370>,) ##顯示cell說明函數multiplyByFactor是閉包
<function multiplier.<locals>.multiplyByFactor at 0x000001A961B79F28>###這個返回值只說明multiplier內嵌了函數multiplyByFactor,並不表示multiplyByFactor是閉包
非閉包嵌套函數
>>> def multiplier(factor):
def multiplyByFactor(number):
return(number*number2)###未引用外層函數的變量
print(multiplyByFactor.__closure__)
return multiplyByFactor
>>> number2 =3
>>> multiplier(2)
None ###說明multiplyByFactor函數不是一個閉包函數,由於它引用的變量是本身的變量和全局變量,未引用外層函數變量
<function multiplier.<locals>.multiplyByFactor at 0x000001A961B92048>
>>> def multiplier(factor):
def multiplyByFactor(number):
return(number*factor*number2)###引用自身變量、外層函數變量、全局變量也不是閉包
print(multiplier.__closure__)
return multiplyByFactor
>>> number2 =3
>>> multiplier(2)
None
<function multiplier.<locals>.multiplyByFactor at 0x000001A961B79F28>
nonlocal函數可使內部函數從新對外層函數變量進行重綁定
>>> def counter():
counter = 0
def do_nonlocal():
nonlocal counter
counter+=1
return counter
return do_nonlocal
>>> ct = counter()
>>> print(ct())
1
>>> print(ct())
2
>>> print(ct())
3
>>> ct = counter() ###counter=0被重定向爲1
>>> print(ct())
1
注意:若是內層函數變量名與外部函數變量名重複,外部函數變量名會覆蓋內層函數變量名
提示:Inspection info: This inspection detects shadowing names defined in outer scopes.
def scope_test(): def func_local(): ##Inspection info: This inspection detects shadowing names defined in outer scopes. parameter = 'local parameter' def statement_nonlocal(): nonlocal parameter parameter = 'nonlocal parameter' def statement_global(): global parameter parameter = 'global parameter' parameter = 'out scope parameter' func_local() print('After local assignment:',parameter) statement_nonlocal() print('After nonlocal assignmet:',parameter) statement_global() print("After global assignment:",parameter) if __name__ == '__main__': scope_test() print('now the parameter is:',parameter)