Python 知識點 閉包延遲繫結

2021-09-25 16:19:49 字數 1987 閱讀 4994

在乙個函式內部定義另乙個函式,外部的函式為外函式,內部的函式為內函式,內函式裡運用了外函式的臨時變數,並且外函式的返回值是內函式的引用。這就形成了乙個閉包。

通常情況下,乙個函式執行結束後,函式內部的所有東西都會被釋放掉,區域性變數也會消失。但是如果外函式在結束時發現自己的臨時變數會在內函式中用到時,就會把這個臨時變數繫結給內函式,然後外函式才結束。

有一道很經典的案例:

def multipliers():

return [lambda x: i * x for i in range(4)]

print ([m(2) for m in multipliers()])

可能我們會認為,上面的函式將輸出為[0, 2, 4, 6],但其實輸出的是[6, 6, 6, 6],這就是閉包導致的。

閉包函式返回內部函式的引用(即定義的lambda匿名函式),外函式呼叫結束時會將被內函式引用的區域性變數(亦稱為閉包變數)繫結至內函式。而延遲繫結指的是,只有在呼叫內函式時,才會訪問閉包變數所指向的物件,不呼叫時不會訪問閉包變數所指向的物件。

上面的例子相當於:

def multipliers():

funcs =

for i in range(4):

def bar(x):

return x*i

return funcs

print ([m(2) for m in multipliers()] )

來看下不呼叫內函式的情況:

def multipliers():

result =

for i in range(4):

print(i)

def func(x):

print("test")

return i * x

return result

multipliers()

輸出為

012

3

可以從上面的**看出,未輸出test字元,說明我們沒有呼叫內函式,在我們沒有呼叫內函式的同時,迴圈的 i 變數最後指向了3,當外函式發現自己的臨時變數會在內函式中用到時,就把i=3繫結給了內函式,這時外函式已經呼叫結束。所以當我們呼叫內函式時,相當於這段偽**(不能執行的**):

return [lambda x: 3 * x, lambda x: 3 * x, lambda x: 3 * x, lambda x: 3 * x]
所以輸出的結果為[6,6,6,6]

將每個迴圈的 i 值繫結給內函式就行了,也叫做立即繫結

多加個預設引數  i=i

def multipliers():

return [lambda x,i=i: i * x for i in range(4)]

相當於:

def multipliers():

funcs =

for i in range(4):

def bar(x, i=i):

return x * i

return funcs

print ([m(2) for m in multipliers()] )

這樣子就把迴圈過程的每個 i 變數都繫結到內函式了,相當於這段偽**:

return [lambda x: 0 * x, lambda x: 1 * x, lambda x: 2 * x, lambda x: 3 * x]
def multipliers():

for i in range(4):

yield lambda x : i * x

print([m(2) for m in multipliers()])

Python閉包的延遲繫結

1.什麼是閉包,閉包必須滿足以下3個條 2.閉包的優點def add a def add b return a b return add ad 2 2 計算2 2的值,用類實現的話,相對麻煩 閉包使用nonlocal deftester start state start defnested lab...

python 閉包 乙個很小知識點

修改前 返回x的乘法函式,是函式,呼叫才執行 defmake return lambda x i x for i in range 3 for r in make print r 4 期望輸出 04 8實際輸出 88 8原因 i因為閉包延遲繫結,到執行的時候已經為2 所以引數4一直只和最終的2相乘 ...

python包匯入的知識點

目錄 包匯入的搜尋路徑 init 檔案的作用 包內相對匯入 包匯入的搜尋路徑和python模組匯入的搜尋路徑和順序完全一樣,具體可以參看筆者的這篇文章。但是要注意的是,這裡的搜尋路徑指的是對最外層的那個包,例如from dir1.dir2 import mod語句,這裡的搜尋路徑指的是對dir1的搜...