標籤:def 結束 sig enc ble 局部變數 而且 UNC before
1、global關鍵字的作用
如果在函數中需要修改全域變數,則需要使用該關鍵字,具體參見下面例子。
variable=100def function():print(variable) #在函數內不對全域變數修改,直接存取是沒問題的,不會報錯function() #輸出100
variable=100def function():result=variable+111print(result) #在函數內不對全域變數修改,直接使用是沒問題的,不會報錯function() #輸出211
variable=100def function():variable+=111print(variable) #顯示local variable ‘variable‘ referenced before assignment。#即在函數局部範圍中直接改變全域變數的值會報錯function()
variable=100def function():variable=1000 #此時修改variable變數的值不會報錯,因為已經在函數局部範圍內重新定義variable,會覆蓋全域variable。variable+=111print(variable)function() #輸出1111print(variable) #輸出100,雖然函數內部重新覆蓋了variable,但是全域variable並未變,依然還是100
那如果不再函數內部重新為全域變數賦值,又想改變全域變數的值,應該怎麼做呢?這就要使用global關鍵字了,如下。
variable=100def function():global variable #使用global關鍵字,表明variable是全域的,此時就可以了直接在函數局部範圍內改變variable的值了variable+=111print(variable) #輸出211function()print(variable) #輸出211,這和上面的不一樣了,發現全域變數variable本身也改變了
總結:global的作用就是在“函數局部範圍”內聲明表示一個全域變數,從而可以在函數內部修改全域變數的值(否則只能訪問不能修改),而且函數內部改變的全域變數的值也會改變。
2、函數局部範圍
函數的局部範圍是不能夠儲存資訊的,即在函數內部聲明變數在函數調用結束之後函數裡面儲存的資訊就被銷毀了,包括函數的參數,如下。
def fun(step):num=1num+=stepprint(num)i=1while(i<5):fun(3) #連續調用函數4次,每次輸出的值都是4,即3+1,這說明每次調用fun函數之後,函數內部定義局部變數num就被銷毀了,#沒有儲存下來,說明函數的局部範圍被銷毀了。那如果要儲存函數的局部變數,怎麼辦呢?引入“閉包”。i+=1
3、閉包——裝飾器的本質也是閉包
“閉包”的本質就是函數的嵌套定義,即在函數內部再定義函數,如下所示。
“閉包”有兩種不同的方式,第一種是在函數內部就“直接調用了”;第二種是“返回一個函數名稱”。
(1)第一種形式——直接調用
def Maker(name):num=100def func1(weight,height,age):weight+=1height+=1age+=1print(name,weight,height,age)func1(100,200,300) #在內部就直接調用“內建函式”Maker(‘feifei‘) #調用外部函數,輸出 feifei 101 201 301
(2)第二種形式——返回函數名稱
def Maker(name):num=100def func1(weight,height,age):weight+=1height+=1age+=1print(name,weight,height,age)return func1 #此處不直接調用,而是返回函數名稱(Python中一切皆對象)maker=Maker(‘feifei‘) #調用封裝器maker(100,200,300) #調用內建函式
(3)“閉包”的作用——儲存函數的狀態資訊,使函數的局部變數資訊依然可以儲存下來,如下。
ef Maker(step): #封裝器num=1def fun1(): #內建函式nonlocal num #nonlocal關鍵字的作用和前面的local是一樣的,如果不使用該關鍵字,則不能再內建函式改變“外部變數”的值num=num+step #改變外部變數的值(如果只是訪問外部變數,則不需要適用nonlocal)print(num)return fun1#=====================================#j=1func2=Maker(3) #調用外部封裝器while(j<5):func2() #調用內建函式4次 輸出的結果是 4、7、10、13j+=1
從上面的例子可以看出,外部裝飾器函數的局部變數num=1、以及調用裝飾器Maker(3)時候傳入的參數step=3都被記憶了下來,所以才有1+3=4、4+3=7、7+3=10、10+3=13.
從這裡可以看出,Maker函數雖然調用了,但是它的局部變數資訊卻被儲存了下來,這就是“閉包”的最大的作用——儲存局部資訊不被銷毀。
4、nonlocal關鍵字的作用
該關鍵字的作用和local的作用類似,就是讓“內建函式”可以修改“外部函數(裝飾器)”的局部變數值。詳細資料這裡不做討論。
Python中的閉包到底有什麼用