在循环中创建函数 [英] Creating functions in a loop
问题描述
我试图在循环内部创建函数并将它们存储在字典中。
问题是,字典中的所有条目似乎都会映射到最后创建的函数。代码如下所示:
d = {}
def test(** kwargs):
在kwargs中为k:
def f():
print k,kwargs [k]
d [k] = f
f()
test
print'应该输出和以前一样的输出'
d ['foo']()
d ['bar']()
输出:
foo 1
bar 2
应该打印与之前相同的输出
bar 2
bar 2
任何想法为什么?
后期绑定 - 每个函数尽可能晚地查找 k
(因此,当在 test
,这发生在循环结束后)。
$ 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 2
Any 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 f
and in your loop use f = make_f(kwargs, k)
instead of the def
statement.
这篇关于在循环中创建函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!