對Python中閉包的理解
阿新 • • 發佈:2018-12-14
定義
Python閉包表現為:如果在一個內部函式裡,對在外部作用域(非全域性作用域)的變數進行引用,那麼內部函式就被認為是閉包(closure)。
def outer(a):
b = 1
def inner():
# 內部函式inner中用到了外部函式的變數
print(a+b)
#外部函式outer的返回值是內部函式的引用
return inner
demo = outer(2)
type(demo) # <type 'function'>
demo.__name__ # 'inner'
demo() # 3
一般情況下,一個函式結束的時候,會把自己的臨時變數都釋放還給記憶體,之後變數都不存在了。但是閉包是一個特別的情況。外部函式發現,自己的臨時變數會在將來的內部函式中用到,自己在結束的時候,返回內函式的同時,會把外函式的臨時變數送給內函式繫結在一起。所以外函式已經結束了,呼叫內函式的時候仍然能夠使用外函式的臨時變數。
建立一個Python閉包
Python閉包(closure)必須滿足以下三點標準:
- 必須有一個內嵌函式
- 內嵌函式必須用到定義在外部函式內的區域性變數
- 外部函式必須返回內嵌函式
注意事項
閉包中不能修改外部作用域的區域性變數的,
def outer():
a = 1
def inner():
a = a + 1
return a
return inner
demo = outer()
print(demo()) # Error
在閉包inner()中,變數a在賦值符號"="的左面,會被python認為是inner()中的區域性變數,再接下來執行printa()時,程式執行至a = a + 1時,因為先前已經把a歸為inner()中的區域性變數,所以python會在inner()中去找在賦值語句右面的a的值,結果找不到,就會報錯。
如果你非要修改也是可以的,有兩種方法:
def outer(): b = 1 # a和b都是閉包變數 c = [3] #這裡對應修改閉包變數的方法2 def inner(): #內函式中想修改閉包變數 # 方法1 nonlocal關鍵字宣告 nonlocal b b += 1 # 方法2,把閉包變數修改成可變資料型別 比如列表 c[0] += 1 print(b) print(c[0]) # 外函式的返回值是內函式的引用 return inner demo = outer() demo() # 2 4
- 在python3中,可以用nonlocal 關鍵字宣告 一個變數, 表示這個變數不是區域性變數空間的變數,需要向上一層變數空間找這個變數。
- 在python2中,沒有nonlocal這個關鍵字,我們可以把閉包變數改成可變型別資料進行修改,比如列表。
閉包的作用(待補)
- 當閉包執行完後,仍然能夠保持住當前的執行環境
- 閉包可以根據外部作用域的區域性變數來得到不同的結果