Python lambda作为常量函子

Python lambda作为常量函子,python,lambda,Python,Lambda,我有labdas的代码,每次创建函数对象时我都会检查它是否不同(不是引用同一个对象), 但它并不像我预期的那样有效。有没有办法,或者我应该使用一个函子来做这件事,即使我有常数数据插入到lambda的身体里 pairs = [('abc', 'xyz'), ('123', '987'), ('abc', '987')] pairLambs = [] for p in pairs: pairLambs.append(lambda: print(p)) pairLambs[0]() pa

我有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')

如果你想“专门化”函数,你应该看看
functools

import functools

pairs = [('abc', 'xyz'), ('123', '987'), ('abc', '987')]
pairLambs = []
for p in pairs:
    pairLambs.append(functools.partial(print, p))

这将给出您期望的结果。

这就是python中闭包的工作方式。要实现您的目标,您可以执行以下操作:

 for p in pairs:
     def closure(_p):
         return lambda: print(_p)
     pairLambs.append(closure(p))

这是一个众所周知的问题-因为在定义
lambda
时,您没有绑定
p
的当前值,调用时它使用
p
的当前值。解决方案是使用具有默认值的命名参数来绑定
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]()

不适用于Python2.x,其中,
print
是一个语句而不是函数。是的,实际上我在Python2.7中这样做了,只是使用了
from\uuuuuuuuuuuuuuuuuuuu导入print\u函数
谢谢,但是我需要labdas主体更复杂一点,我实际上是在Qt(PySide)中做GUI应用程序我想处理一些影响gui的非gui对象的回调。。。这实际上只是一个理想的例子。我相信你可以用
functools
比lambda做更多的事情——不管怎样,lambda并不打算做复杂的事情。与其说
这是一个众所周知的gotcha
,不如说,
一个lambda在调用时会被评估。由于所有lambda都引用相同的标识符
p`,该标识符在迭代过程中会发生变化,因此它指向的最后一个对象是与所有lamba表达式关联的对象`@Abhijit:这仍然是一个问题,就像“不明显且不一定是直观的行为”一样,这是众所周知的。谢谢,我怀疑这和命名有关,但我也有一种预感,它一定会以某种方式起作用。带默认参数的解决方案正是我需要的!谢谢,我想避免定义新的东西(函数、类)。另外,我更喜欢一个函子:
类PairFunctor:def\uuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu(self,pair):self.pair=PairFunctor(p))