lambda 函数的范围及其参数? [英] Scope of lambda functions and their parameters?
问题描述
我需要一个对于一系列 gui 事件几乎完全相同的回调函数.根据调用它的事件,该函数的行为会略有不同.对我来说似乎是一个简单的案例,但我无法弄清楚 lambda 函数的这种奇怪行为.
I need a callback function that is almost exactly the same for a series of gui events. The function will behave slightly differently depending on which event has called it. Seems like a simple case to me, but I cannot figure out this weird behavior of lambda functions.
所以我在下面有以下简化代码:
So I have the following simplified code below:
def callback(msg):
print msg
#creating a list of function handles with an iterator
funcList=[]
for m in ('do', 're', 'mi'):
funcList.append(lambda: callback(m))
for f in funcList:
f()
#create one at a time
funcList=[]
funcList.append(lambda: callback('do'))
funcList.append(lambda: callback('re'))
funcList.append(lambda: callback('mi'))
for f in funcList:
f()
这段代码的输出是:
mi
mi
mi
do
re
mi
我期望:
do
re
mi
do
re
mi
为什么使用迭代器会把事情搞砸?
Why has using an iterator messed things up?
我尝试过使用深层复制:
I've tried using a deepcopy:
import copy
funcList=[]
for m in ('do', 're', 'mi'):
funcList.append(lambda: callback(copy.deepcopy(m)))
for f in funcList:
f()
但这有同样的问题.
推荐答案
这里的问题是 m
变量(引用)从周围的作用域中获取.只有参数保存在 lambda 范围内.
The problem here is the m
variable (a reference) being taken from the surrounding scope.
Only parameters are held in the lambda scope.
要解决这个问题,您必须为 lambda 创建另一个作用域:
To solve this you have to create another scope for lambda:
def callback(msg):
print msg
def callback_factory(m):
return lambda: callback(m)
funcList=[]
for m in ('do', 're', 'mi'):
funcList.append(callback_factory(m))
for f in funcList:
f()
在上面的例子中,lambda 也使用了周围的作用域来查找 m
,但是这个时间是 callback_factory
范围,每个 callback_factory
创建一次打电话.
In the example above, lambda also uses the surounding scope to find m
, but this
time it's callback_factory
scope which is created once per every callback_factory
call.
或者使用 functools.partial:
from functools import partial
def callback(msg):
print msg
funcList=[partial(callback, m) for m in ('do', 're', 'mi')]
for f in funcList:
f()
这篇关于lambda 函数的范围及其参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!