Python lambda 作为常量函子

7 投票
3 回答
1040 浏览
提问于 2025-04-18 12:55

我有一些使用了lambda表达式的代码,我检查过每次创建的函数对象都是不同的(不是指向同一个对象),但是它的表现和我预期的不一样。有没有什么方法或者我应该使用一个函数对象(functor)来实现这个,即使我在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')

3 个回答

2

如果你想要“专门化”一个函数,可以看看 functools 这个工具:

import functools

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

这样就能得到你想要的结果。

2

这就是Python中闭包的工作原理。为了实现你想要的效果,你可以这样做:

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

这是一个大家都知道的坑——因为在定义这个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]()

撰写回答