閉包: 閉包指延伸了作用域的函數,其中包含函數定義體中引用、但是不在定義體中定義的非全局變量。
例子:
def make_averager():
series = []
def averager(new_value):
series.append(new_value)
total = sum(series)
return total/len(series)
return averager
avg = make_averager()
print(avg(10)) #10
print(avg(11)) #10.5
print(avg(12)) #11
按以往的常識來說, make_averager() 中的series 隨着return 語句結束, 應該出棧, 但這裏卻可以繼續保存值, 並且 參與到內部函數的計算中.
原因 :
1) make_averager 函數已經返回了,而它的本地作用域也一去不復返了, 但是series在averager()函數中是自由變量(free variable). 自由變量指未在本地作用域中綁定的變量
2) 通過打印avg的自由變量,
print(avg.__code__.co_freevars) #('series',)
發現avg中存在自由變量series
故 series 綁定在返回的 avg 函數的 __closure__ 屬性中, 內部函數依舊可以使用它
綜上,閉包是一種函數,它會保留定義函數時存在的自由變量的綁定,這樣調用函數時,雖然定義作用域不可用了,但是仍能使用那些綁定
注: 只有嵌套在其他函數中的函數纔可能需要處理不在全局作用域中的外部變量
參考文獻: 《fluent Python》 --7.5