簡單的說,就是某個內部函式被當做物件返回時,夾帶了這個內部函式之外的變數,這就形成了乙個閉包。
def logging(level):
def say(words):
print '{} is a outer variable'.format(level)
print "say is ".format(words, level) # 夾帶外部變數level
return say # 返回的是say這個函式,它夾帶了它之外的level變數
say = logging('right')
say('hello') # right is a outer variable
# say hello is right
print say.__closure__ #(,)
print say.func_closure[0].cell_contents # right
通過閉包,執行say(『hello』),不僅能夠完美執行say函式的功能,還可以在say函式中引用了外部的乙個變數,進而可以實現更加多樣化的功能。試想一下,如果外部變數不是level,而是乙個函式物件呢?這裡就引出了裝飾器的概念。
在上面的例子中,內部函式say就是閉包函式,其實閉包函式相對與普通函式會多出乙個closure的屬性,裡面定義了乙個元組用於存放所有的cell物件,每個cell物件一一儲存了這個閉包中所有的外部變數。
python閉包之經典的for迴圈問題
上個例子中,內部函式引用的外部變數是外部函式的引數,而下面這個例子,引用的是外部函式中的區域性變數,它們相對於內部函式,都是外部變數,符合閉包的定義。
f1, f2, f3 = count() # 將fs中的三個f分別傳遞給f1,f2,f3
print(f1()), print(f2()), print(f3()) # 9 9 9
f1(), f2(), f3() 結果不應該是 1, 4, 9 嗎,實際結果為什麼都是 9 呢?
原因就是當 count() 函式返回了 3 個函式時,這 3 個函式所引用的變數 i 的值已經變成了 3。由於 f1、f2、f3 並沒有被呼叫,所以,此時他們並未計算 i*i,當 f1 被呼叫時,i 已經變為 3 了。
如何修改?
方法一為變數 i 建立乙個封閉的作用域,將i傳遞到封閉的作用域內,即將 i 傳遞給 j。
python中閉包 python中的閉包
一 定義 如果在乙個內部函式裡,對在外部作用域 但不是在全域性作用域 的變數進行引用,那麼內部函式就被認為是閉包 closure 這個定義是相對直白的,閉包有三個條件 1.函式巢狀 2,內部函式呼叫外部函式的變數 3.返回內部函式 defa a defb b s a breturnsreturnb ...
python 閉包 Python中的閉包
一 什麼是閉包 在談之前,我們先來說說作用域,變數的作用域無非就兩種 全域性變數和區域性變數。函式內部可以直接讀取全域性變數,但是在函式外部無法讀取函式內部的區域性變數。出於種種原因,我們有時候需要獲取到函式內部的區域性變數。但是,正常情況下,這是辦不到的!只有通過變通的方法才能實現。於是就引入了閉...
閉包 Python中的閉包
通俗地講就是別人家有某個東西,你想拿到但是因為許可權不夠 不打死你才怪 但是你可以跟家裡的孩子套近乎,通過他拿到!這個家就是區域性作用域,外部無法訪問內部變數,孩子是從家裡返回物件,對家裡的東西有訪問許可權,借助返回物件間接訪問內部變數!def outer 別人家 x 10 別人家裡的東西 def ...