什麼是閉包?閉包有什麼用?為什麼要用閉包?今天我們就帶著這3個問題來一步一步認識閉包。閉包和函式緊密聯絡在一起,介紹閉包前有必要先介紹一些背景知識,諸如巢狀函式、變數的作用域等概念
作用域作用域是程式執行時變數可被訪問的範圍,定義在函式內的變數是區域性變數,區域性變數的作用範圍只能是函式內部範圍內,它不能在函式外引用。
def foo():
num = 10 # 區域性變數
print(num) # nameerror: name 'num' is not defined
定義在模組最外層的變數是全域性變數,它是全域性範圍內可見的,當然在函式裡面也可以讀取到全域性變數的。例如:
num = 10 # 全域性變數
def foo():
print(num) # 10
巢狀函式
函式不僅可以定義在模組的最外層,還可以定義在另外乙個函式的內部,像這種定義在函式裡面的函式稱之為巢狀函式(nested function)例如:
def print_msg():
# print_msg 是外圍函式
msg = "zen of python"
def printer():
# printer是巢狀函式
print(msg)
printer()
# 輸出 zen of python
print_msg()
對於巢狀函式,它可以訪問到其外層作用域中宣告的非區域性(non-local)變數,比如**示例中的變數 msg 可以被巢狀函式 printer 正常訪問。
那麼有沒有一種可能即使脫離了函式本身的作用範圍,區域性變數還可以被訪問得到呢?答案是閉包
函式身為第一類物件,它可以作為函式的返回值返回,現在我們來考慮如下的例子:
def print_msg():
# print_msg 是外圍函式
msg = "zen of python"
def printer():
# printer 是巢狀函式
print(msg)
return printer
another = print_msg()
# 輸出 zen of python
another()
這段**和前面例子的效果完全一樣,同樣輸出 「zen of python」。不同的地方在於內部函式 printer 直接作為返回值返回了。
一般情況下,函式中的區域性變數僅在函式的執行期間可用,一旦 print_msg() 執行過後,我們會認為 msg變數將不再可用。然而,在這裡我們發現 print_msg 執行完之後,在呼叫 another 的時候 msg 變數的值正常輸出了,這就是閉包的作用,閉包使得區域性變數在函式外被訪問成為可能。
閉包避免了使用全域性變數,此外,閉包允許將函式與其所操作的某些資料(環境)關連起來。這一點與物件導向程式設計是非常類似的,在面物件程式設計中,物件允許我們將某些資料(物件的屬性)與乙個或者多個方法相關聯。
一般來說,當物件中只有乙個方法時,這時使用閉包是更好的選擇。來看乙個例子:
def adder(x):
return x + y
adder5 = adder(5)
# 輸出 15
adder5(10)
# 輸出 11
adder5(6)
這比用類來實現更優雅,此外裝飾器也是基於閉包的一中應用場景。
所有函式都有乙個closure屬性,如果這個函式是乙個閉包的話,那麼它返回的是乙個由 cell 物件 組成的元組物件。cell 物件的cell_contents 屬性就是閉包中的自由變數。
>>> adder.__closure__
>>> adder5.__closure__
(,)>>> adder5.__closure__[0].cell_contents
5
這解釋了為什麼區域性變數脫離函式之後,還可以在函式之外被訪問的原因的,因為它儲存在了閉包的 cell_contents中了。
python中閉包 python中的閉包
一 定義 如果在乙個內部函式裡,對在外部作用域 但不是在全域性作用域 的變數進行引用,那麼內部函式就被認為是閉包 closure 這個定義是相對直白的,閉包有三個條件 1.函式巢狀 2,內部函式呼叫外部函式的變數 3.返回內部函式 defa a defb b s a breturnsreturnb ...
python 閉包 Python中的閉包
一 什麼是閉包 在談之前,我們先來說說作用域,變數的作用域無非就兩種 全域性變數和區域性變數。函式內部可以直接讀取全域性變數,但是在函式外部無法讀取函式內部的區域性變數。出於種種原因,我們有時候需要獲取到函式內部的區域性變數。但是,正常情況下,這是辦不到的!只有通過變通的方法才能實現。於是就引入了閉...
閉包 Python中的閉包
通俗地講就是別人家有某個東西,你想拿到但是因為許可權不夠 不打死你才怪 但是你可以跟家裡的孩子套近乎,通過他拿到!這個家就是區域性作用域,外部無法訪問內部變數,孩子是從家裡返回物件,對家裡的東西有訪問許可權,借助返回物件間接訪問內部變數!def outer 別人家 x 10 別人家裡的東西 def ...