一、global關鍵字的做用閉包
若是在函數中須要修改全局變量,則須要使用該關鍵字,具體參見下面例子。函數
variable=100 def function(): print(variable) #在函數內不對全局變量修改,直接訪問是沒問題的,不會報錯 function() #輸出100
variable=100 def function(): result=variable+111 print(result) #在函數內不對全局變量修改,直接使用是沒問題的,不會報錯 function() #輸出211
variable=100 def function(): variable+=111 print(variable) #顯示local variable 'variable' referenced before assignment。 #即在函數局部做用域中直接改變全局變量的值會報錯 function()
variable=100 def function(): variable=1000 #此時修改variable變量的值不會報錯,由於已經在函數局部做用域內從新定義variable,會覆蓋全局variable。 variable+=111 print(variable) function() #輸出1111 print(variable) #輸出100,雖然函數內部從新覆蓋了variable,可是全局variable並未變,依然仍是100
那若是再也不函數內部從新爲全局變量賦值,又想改變全局變量的值,應該怎麼作呢?這就要使用global關鍵字了,以下。spa
variable=100 def function(): global variable #使用global關鍵字,代表variable是全局的,此時就能夠了直接在函數局部做用域內改變variable的值了 variable+=111 print(variable) #輸出211 function() print(variable) #輸出211,這和上面的不同了,發現全局變量variable自己也改變了
總結:global的做用就是在「函數局部做用域」內聲明表示一個全局變量,從而能夠在函數內部修改全局變量的值(不然只能訪問不能修改),並且函數內部改變的全局變量的值也會改變。code
二、函數局部做用域對象
函數的局部做用域是不可以保存信息的,即在函數內部聲明變量在函數調用結束以後函數裏面保存的信息就被銷燬了,包括函數的參數,以下。blog
def fun(step): num=1 num+=step print(num) i=1 while(i<5): fun(3) #連續調用函數4次,每次輸出的值都是4,即3+1,這說明每次調用fun函數以後,函數內部定義局部變量num就被銷燬了, #沒有保存下來,說明函數的局部做用域被銷燬了。那若是要保存函數的局部變量,怎麼辦呢?引入「閉包」。 i+=1
三、閉包——裝飾器的本質也是閉包作用域
「閉包」的本質就是函數的嵌套定義,即在函數內部再定義函數,以下所示。io
「閉包」有兩種不一樣的方式,第一種是在函數內部就「直接調用了」;第二種是「返回一個函數名稱」。function
(1)第一種形式——直接調用class
def Maker(name): num=100 def func1(weight,height,age): weight+=1 height+=1 age+=1 print(name,weight,height,age) func1(100,200,300) #在內部就直接調用「內部函數」 Maker('feifei') #調用外部函數,輸出 feifei 101 201 301
(2)第二種形式——返回函數名稱
def Maker(name): num=100 def func1(weight,height,age): weight+=1 height+=1 age+=1 print(name,weight,height,age) return func1 #此處不直接調用,而是返回函數名稱(Python中一切皆對象) maker=Maker('feifei') #調用包裝器 maker(100,200,300) #調用內部函數
(3)「閉包」的做用——保存函數的狀態信息,使函數的局部變量信息依然能夠保存下來,以下。
ef Maker(step): #包裝器 num=1 def fun1(): #內部函數 nonlocal num #nonlocal關鍵字的做用和前面的local是同樣的,若是不使用該關鍵字,則不能再內部函數改變「外部變量」的值 num=num+step #改變外部變量的值(若是隻是訪問外部變量,則不須要適用nonlocal) print(num) return fun1 #=====================================# j=1 func2=Maker(3) #調用外部包裝器 while(j<5): func2() #調用內部函數4次 輸出的結果是 四、七、十、13 j+=1
從上面的例子能夠看出,外部裝飾器函數的局部變量num=一、以及調用裝飾器Maker(3)時候傳入的參數step=3都被記憶了下來,因此纔有1+3=四、4+3=七、7+3=十、10+3=13.
從這裏能夠看出,Maker函數雖然調用了,可是它的局部變量信息卻被保存了下來,這就是「閉包」的最大的做用——保存局部信息不被銷燬。
四、nonlocal關鍵字的做用
該關鍵字的做用和local的做用相似,就是讓「內部函數」能夠修改「外部函數(裝飾器)」的局部變量值。詳細信息這裏不作討論。