什麼是閉包
Objects are data with methods attached. Closures are functions with data attached.
一般來說,我們都非常熟悉面向對象(OOD)語言中的對象的概念。所謂對象(Object),指的是附帶相應方法的數據。那麼相對而言,閉包(closure)指的則是附帶相應數據的函數。換句話說,閉包函數能夠引用一些並不在當前代碼全局上下文中定義的變量。這些被引用的變量(稱爲自由變量)是在閉包函數被定義的位置的所在的代碼中定義的。這樣的一些函數被稱爲閉包。
Python中的閉包
由於在Python中,函數也是第一類對象,所以與字符串,數字或其他任何我們所熟悉的對象一樣,函數也可以被賦值給一個變量,作爲另一個函數的返回值,或作爲一個輸入參數傳遞給另一個函數。這就使得定義閉包非常的方便,如下面的例子所示。
def constant_adder(x):
constant = x
def adder(y):
y = y + constant
return y
return adder
# Given the above function
>>> f1 = constant_adder(1)
>>> f1(2)
>>> 3
>>> f2 = constant_adder(10)
>>> f2(2)
>>> 12
在上述例子中,我們可以發現在調用f1
和f2
的時候,constant_adder
的作用域事實上已經結束。這裏的constant
就是一個自由變量,我們仍然在f1
和f2
中調用了在constant_adder
中的定義的constant
變量,這就是一個附帶相應數據的函數。
另外,在Python3.x以前,我們只能在閉包中取得自由變量的值,但無法改變自由變量的值。重新賦值自由變量的行爲將會導致一個作用域爲當前函數的局部變量的產生。Python3.0引入了nonlocal
關鍵字,使得我們不僅能夠讀取自由變量,也能夠重新賦值自由變量。如下面的例子所示。
def foo():
x = 1
def show():
print("x is {}".format(x))
def change():
nonlocal x
x = 2
return show, change
# Given the above function
>>> show, change = foo()
>>> show()
>>> x is 1
>>> change()
>>> show()
>>> x is 2
Reference
https://stackoverflow.com/questions/13857/can-you-explain-closures-as-they-relate-to-python
http://mrevelle.blogspot.com/2006/10/closure-on-closures.html