为什么这不起作用?
u = {}
for me in ['foo', 'bar']:
def callback():
return 'I am %s' % me
u[me] = callback
我得到的输出是:
>>> u['foo']()
'I am bar'
似乎callback
在最近的迭代中定义了一次。
编辑
正如kawadhiya21所提出的,课堂方法可行:
class CallbackFactory():
def __init__(self, me):
self.me = me
def __call__(self):
return 'I am %s' % self.me
u = {}
for me in ['foo', 'bar']:
u[me] = CallbackFactory(me)
但它比前一种方法复杂得多。
答案 0 :(得分:8)
您的所有函数都引用相同的变量me
。当您尝试调用该函数时,me
的值为'bar'
,因为它是循环结束时的内容。
如果希望me
为函数的每个定义采用不同的值,则每个函数都需要自己的变量副本。
u = {}
for me in ['foo', 'bar']:
def callback(me_copy=me):
return 'I am %s' % me_copy
u[me] = callback
如果您愿意,可以将其缩短为:
u = {}
for me in ['foo', 'bar']:
u[me] = lambda me_copy=me: 'I am %s'%me_copy
甚至
u = { me: (lambda me_copy=me: 'I am %s'%me_copy) for me in ('foo', 'bar') }
答案 1 :(得分:2)
首先,在您的示例中,u['foo']
根本不应返回字符串,而应返回函数句柄。 :)编辑:这句话不再相关。
其次,您的函数callback
使用来自外部作用域的me
。如果在外部范围中更改此值(在您的情况下是循环),则函数的输出也会更改。
要解决此问题,您需要将me
部分功能作为自己的范围,例如通过做:
def callback(int_me=me):
return 'I am %s' % int_me
答案 2 :(得分:1)
你想要定义一系列回调,而不是简单地保存一堆输出,对吧?定义一个绑定所需参数的函数,如下所示:
def make_callback(param):
def callback():
return 'I am %s' % param
return callback
for me in ['foo', 'bar']:
u[me] = make_callback(me)
>>> u["foo"]()
'I am foo'
答案 3 :(得分:0)
每次在循环中重新定义回调()。所以最新版本可行。我认为你应该使用基于类的方法。