閉包的定義:python
閉包就是一個函數,這個函數能夠記住封閉做用域裏的值,而無論封閉做用域是否還在內存中。閉包
來一個例子:app
def happy_add(a): print 'id(a): %x' % id(a) def do_add(b): return a + b print 'id(do_add): %x' % id(do_add) return do_add test_one = happy_add(1) test_one(9) print repr(test_one) print '\n------------------\n' test_other = happy_add(3) del happy_add test_other(16) print repr(test_other)
執行結果是:函數
id(a): 7fae91d05788 id(do_add): 10a94a0c8 <function do_add at 0x10a94a0c8> ------------------ id(a): 7fae91d05758 id(do_add): 10a94a6e0 <function do_add at 0x10a94a6e0>
分析: 對象
首先id(x)是求出x在內存中的地址。blog
兩次id(a)不一樣,說明變量綁定到各自的嵌套函數對象。內存
每次調用happy_add()會產生不一樣的對象,會存儲在不一樣的地方。作用域
封閉命名空間刪除(del happy_add)也不會影響閉包函數的執行。it
就這麼一個函數寫成class:io
class happy_add: def __init__(self, x, y): self.x = x self.y = y def add(self): return self.x + self.y test_one = happy_add(1, 9) print test_one.add()
是否是很不美觀,有種小題大作的感受。
閉包的判斷:
(1)一個嵌套函數(函數裏面的函數)
(2)嵌套函數用到封閉函數裏定義的一個或多個值
(3)封閉函數的返回值是嵌套函數
何時用閉包:
閉包的好處是避免使用全局變量和提供了數據隱藏的一種可選形式。問題是這些均可以經過class來實現,爲何還要有closure呢?一般,當屬性和方法不少的時候用類。反之(大多數狀況一個方法),則選擇closure,closure會是一個更加優雅簡潔的解決方案。