[英]currying functions in python in a loop
所以這里有一些代碼簡化了我一直在做的工作:
vars = {
'a':'alice',
'b':'bob',
}
cnames = ['charlie', 'cindy']
commands = []
for c in cnames:
kwargs = dict(vars)
kwargs['c'] = c
print kwargs
commands.append(lambda:a_function(**kwargs))
print commands
def a_function(a=None, b=None, c=None):
print a
print b
print c
for c in commands:
print "run for "+ repr(c)
c()
這是它的輸出:
{'a': 'alice', 'c': 'charlie', 'b': 'bob'}
{'a': 'alice', 'c': 'cindy', 'b': 'bob'}
[<function <lambda> at 0x1001e9a28>, <function <lambda> at 0x1001e9e60>]
run for <function <lambda> at 0x1001e9a28>
alice
bob
cindy
run for <function <lambda> at 0x1001e9e60>
alice
bob
cindy
我希望得到查理,然后cindy,為什么cindy被展示兩次?
您遇到了經典的綁定時間問題,@ Mike的解決方案是經典的解決方案。 一個很好的選擇是編寫一個更高階的函數:
def makecall(kwargs):
def callit():
return a_function(**kwargs)
return callit
並在循環中使用commands.append(makecall(kwargs))
。 兩個解決方案都遵循相同的原則(通過參數的通過強制早期綁定 - 在我的情況下是一個普通的參數,@ Mike的命名參數的默認值); 選擇只是風格或優雅的問題(我,雖然我在超簡單的情況下容忍lambda
,只要最微妙的復雜介入,我非常喜歡好的舊def
;-)。
在調用函數之前,函數的主體不會運行。 當你執行lambda: a_function(**kwargs)
,在實際調用函數之前不會查找kwargs
。 此時,它被分配給您在循環中創建的最后一個。
獲得所需結果的一個解決方案是執行commands.append(lambda kwargs=kwargs: a_function(**kwargs))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.