我有labdas的代码,我每次创建函数对象时都检查过它是不同的(不是对同一个对象的引用), 但它没有像我期望的那样工作。有没有办法如何或者我应该使用仿函数来做它,即使我有插入lambda体内的常数数据?
pairs = [('abc', 'xyz'), ('123', '987'), ('abc', '987')]
pairLambs = []
for p in pairs:
pairLambs.append(lambda: print(p))
pairLambs[0]()
pairLambs[1]()
pairLambs[2]()
输出:
('abc', '987')
('abc', '987')
('abc', '987')
但我需要:
('abc', 'xyz')
('123', '987')
('abc', '987')
答案 0 :(得分:10)
这是一个众所周知的问题 - 因为在定义p
时你没有绑定lambda
的当前值,所以在调用它时会使用当前值p
。解决方案是使用带有默认值的命名arg来绑定p
的“当前”(定义时间)值:
pairs = [('abc', 'xyz'), ('123', '987'), ('abc', '987')]
pairLambs = []
for p in pairs:
pairLambs.append(lambda p=p: print(p))
pairLambs[0]()
pairLambs[1]()
pairLambs[2]()
答案 1 :(得分:2)
如果您想专业化'功能,你应该看看functools
:
import functools
pairs = [('abc', 'xyz'), ('123', '987'), ('abc', '987')]
pairLambs = []
for p in pairs:
pairLambs.append(functools.partial(print, p))
这会得到您期望的结果。
答案 2 :(得分:1)
这就是python中的闭包工作方式。要达到你想要的效果,你可以这样做:
for p in pairs:
def closure(_p):
return lambda: print(_p)
pairLambs.append(closure(p))