问题描述
我试图在循环内部创建函数并将它们存储在字典中。
问题是,字典中的所有条目似乎都会映射到最后创建的函数。代码如下所示:
$ b 通过强制早绑定轻松修复:将 def f():更改为 def f (k = k): - 默认值(右边 k 在 k = k 是参数名称 k 的默认值,它是<$ c $中左侧的 k c> k = k )在 def 时间内查找,而不是在 call 时间,所以基本上它们是专门寻找早期绑定的一种方法。
如果您担心 f 获得一个额外的参数(因此可能被错误地调用),还有一种更复杂的方式,它将一个闭包作为函数工厂使用:
def make_f(kwargs,k):
def f():
print k,kwargs [k]
return f
并在循环中使用 f = make_f(kwargs,k)而不是 def 语句。
I'm trying to create functions inside of a loop and storing them in a dictionary.The problem is that all entries in the dictionary seem end up mapping to the last created function. The code goes like this:
d = {} def test(**kwargs): for k in kwargs: def f(): print k, kwargs[k] d[k] = f f() test(foo=1, bar=2) print 'should print the same output as before' d['foo']() d['bar']()This outputs:
foo 1 bar 2 should print the same output as before bar 2 bar 2Any idea why?
解决方案You're running into a problem with late binding -- each function looks up k as late as possible (thus, when called outside test, this happens after the end of the loop).
Easily fixed by forcing early binding: change def f(): to def f(k=k): -- default values (the right-hand k in k=k is a default value for argument name k, which is the left-hand k in k=k) are looked up at def time, not at call time, so essentially they're a way to specifically looking for early binding.
If you're worried about f getting an extra argument (and thus potentially being called erroneously), there's a more sophisticated way which involved using a closure as a "function factory":
def make_f(kwargs, k): def f(): print k, kwargs[k] return fand in your loop use f = make_f(kwargs, k) instead of the def statement.
这篇关于在循环中创建函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!