如果在一個內部函式裡, 對在外部作用域(但不是在全域性作用域) 的變數進行引用, 那麼內部函式就被認為是閉包(closure)。定義在外部函式內的但由內部函式引用或者使用的變數被稱為自由變數。
閉包在函數語言程式設計中是一個重要的概念, Scheme和Haskell便是函數語言程式設計中兩種。 閉包從語法上看很簡單(和內部函式一樣簡單) 但是仍然很有威力。
那麼為什麼你會想要用閉包?
閉包對於安裝計算、 隱藏狀態和在函式物件和作用域中隨意地切換是很有用的。
閉包在GUI或者在很多API支援回撥函式的事件驅動程式設計中是很有些用處的。 以絕對相同的方式, 應用於獲取資料庫行和處理數
據。 回撥就是函式。 閉包也是函式, 但是他們能攜帶一些額外的作用域。 它們僅僅是帶了額外特徵的函式……另外的作用域。
閉包和函式呼叫沒多少相關, 而是關於使用定義在其他作用域的變數。
def counter(start_at=0): count=[start_at] def incr(): count[0]+=1 return count[0] return incr; if __name__=="__main__": print(counter(0)())
counter()做的唯一一件事就是接受一個初始化的值來開始計數, 並將該值賦給列表count唯一一個成員。 然後定義一個incr()的內部函式。
通過在內部使用變數count, 我們建立了一個閉包, 因為它現在攜帶了整個counter()作用域。 incr()增加了正在執行的count然後返回它。
然後最後的魔法就是counter()返回一個incr, 一個(可呼叫的) 函式物件。
注意counter(0)(),counter(0)返回的是incr,一個可呼叫的函式物件,所以後面加()
閉包更適合需要一個必需有自己的作用域的回撥函式情況, 尤其是回撥函式是很小巧而且簡單的, 通常也很聰明。 跟平常一樣, 如果你使用了閉包, 對你的程式碼進行註釋或者用文件字串來解釋你正做的事是很不錯的主意。 【意思是,如果你使用了閉包,就應當加上註釋】