引子
大概一個月前,一個同事問,什么是"閉包",然后整個月好像都在糾結(jié)這個問題啊喂。。。其實(shí)搜搜概念,網(wǎng)上有一大堆,研究一下其實(shí)也不復(fù)雜。然后不知道什么鬼總感覺這東西跟裝飾器有什么數(shù)不清楚的關(guān)系?。ê竺鎸懸黄谑?,又折騰了一下,然后,尼瑪?shù)牧硪粋€同事問,"為什么我們需要閉包"
然后我就無言以對啊,搞明白一個概念,如果沒有什么實(shí)踐價值,有個卵用啊于是在接下來的時間不停的想啊想啊想。。。終于今晚想到了一個絕佳的例子,怎么樣也要記錄一下吧
例子
廢話不多suo了。直接上例子吧。比如math包里面有個log函數(shù),可是我并不知道log2(8)這玩意要寫成math.log(2, 8)還是math.log(8, 2),而且我也不想log2寫一個log10再寫一個吧。。。所以,為了少碼幾個字,我們可以這樣寫:
import math
def my_log(a):
def wrapper(N):
return math.log(N, a)
return wrapper
if __name__ == "__main__":
log2 = my_log(2)
lg = my_log(10)
print log2(8)
print lg(100)
是的,通過log2或者lg,就可以直接計算以2為底或者以10為底的數(shù)的對數(shù)了。而且log2(8)這種寫法,也比較符合正常人的想法。順帶,我們也不需要再單獨(dú)定義兩個函數(shù)了,O(∩_∩)O~
其實(shí),估計不用閉包也會有辦法實(shí)現(xiàn)同樣的功能,但是閉包絕對提供了一種更為優(yōu)(tou)雅(lan)的實(shí)現(xiàn)方式。下面我們說說什么是閉包。
定義
反正,我是不會告訴你,它的官方定義是:
如果在一個內(nèi)部函數(shù)里,對在外部作用域(但不是在全局作用域)的變量進(jìn)行引用,那么內(nèi)部函數(shù)就被認(rèn)為是閉包(closure)
如果要用一個例子來解釋上面這段話的話,可以參考以下代碼:
def outer(outer_para):
def inner(inner_para):
return outer_para + inner_para
return inner
if __name__ == "__main__":
func = outer(5)
print func(10)
接下來再補(bǔ)充完善一下:
- 必須有一個內(nèi)嵌函數(shù)(nested function),也就是在函數(shù)內(nèi)部定義一個函數(shù),比如例子中的inner
- 必須在內(nèi)嵌函數(shù)中調(diào)用上層函數(shù)中的變量,比如在inner中調(diào)用outer_para
- 上層函數(shù)必須返回內(nèi)嵌函數(shù),也就是outer的最后一行必須是
return inner