簡體   English   中英

在循環中在python中調整函數

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM