4 回答

TA貢獻(xiàn)1802條經(jīng)驗 獲得超5個贊
您可以使用具有默認(rèn)值的參數(shù)強(qiáng)制捕獲變量:
>>> for i in [0,1,2,3]:
... adders[i]=lambda a,i=i: i+a # note the dummy parameter with a default value
...
>>> print( adders[1](3) )
4
我們的想法是聲明一個參數(shù)(巧妙地命名i)并給它一個你想要捕獲的變量的默認(rèn)值(值 i)

TA貢獻(xiàn)1864條經(jīng)驗 獲得超2個贊
為了完整性,您對第二個問題的另一個答案是:您可以在functools模塊中使用partial。
通過從運(yùn)營商導(dǎo)入add,Chris Lutz提出的示例變?yōu)椋?/p>
from functools import partialfrom operator import add # add(a, b) -- Same as a + b.adders = [0,1,2,3]for i in [0,1,2,3]: # store callable object with first argument given as (current) i adders[i] = partial(add, i) print adders[1](3)

TA貢獻(xiàn)1818條經(jīng)驗 獲得超7個贊
請考慮以下代碼:
x = "foo"def print_x(): print x x = "bar"print_x() # Outputs "bar"
我想大多數(shù)人都不會發(fā)現(xiàn)這種混亂。這是預(yù)期的行為。
那么,為什么人們認(rèn)為它在循環(huán)中完成時會有所不同?我知道我自己犯了這個錯誤,但我不知道為什么。這是循環(huán)?或者也許是lambda?
畢竟,循環(huán)只是一個較短的版本:
adders= [0,1,2,3]i = 0adders[i] = lambda a: i+a i = 1adders[i] = lambda a: i+a i = 2adders[i] = lambda a: i+a i = 3adders[i] = lambda a: i+a

TA貢獻(xiàn)1876條經(jīng)驗 獲得超5個贊
你的第二個問題已得到解答,但至于你的第一個問題:
封閉捕獲到底是什么?
Python中的范圍是動態(tài)的和詞匯的。閉包將始終記住變量的名稱和范圍,而不是它指向的對象。由于示例中的所有函數(shù)都在同一作用域中創(chuàng)建并使用相同的變量名,因此它們始終引用相同的變量。
編輯:關(guān)于如何克服這個問題的另一個問題,有兩種方法可以想到:
最簡潔但不嚴(yán)格等同的方式是Adrien Plisson推薦的方式。使用額外參數(shù)創(chuàng)建lambda,并將額外參數(shù)的默認(rèn)值設(shè)置為要保留的對象。
每次創(chuàng)建lambda時,創(chuàng)建一個新范圍會更冗長但更少hacky:
>>> adders = [0,1,2,3]>>> for i in [0,1,2,3]:... adders[i] = (lambda b: lambda a: b + a)(i)... >>> adders[1](3)4>>> adders[2](3)5
這里的范圍是使用一個新函數(shù)(lambda,為簡潔起見)創(chuàng)建的,它綁定了它的參數(shù),并傳遞你想要綁定的值作為參數(shù)。但是,在實際代碼中,您很可能會使用普通函數(shù)而不是lambda來創(chuàng)建新范圍:
def createAdder(x): return lambda y: y + x adders = [createAdder(i) for i in range(4)]
添加回答
舉報