Python中lambda函数的可变参数

37 投票
3 回答
41549 浏览
提问于 2025-04-15 23:12

一个 lambda 函数可以有可变数量的参数吗?

举个例子,我想写一个元类,这个元类会为另一个类的每个方法创建一个新方法,而这个新方法会返回原方法的相反值,并且参数数量要一样。

我想用 lambda 函数来实现这个功能。那我该怎么传递参数呢?这是可能的吗?

class Negate(type):
    def __new__(mcs, name, bases, _dict):
        extended_dict = _dict.copy()
        for (k, v) in _dict.items():
            if hasattr(v, '__call__'):
                extended_dict["not_" + k] = lambda s, *args, **kw:  not v(s, *args, **kw)
        return type.__new__(mcs, name, bases, extended_dict)

class P(metaclass=Negate):
    def __init__(self, a):
        self.a = a

    def yes(self):
        return True

    def maybe(self, you_can_chose):
        return you_can_chose

但是结果完全不对:

>>>p = P(0)
>>>p.yes()
True
>>>p.not_yes()     # should be False
Traceback (most recent call last):
  File "<pyshell#150>", line 1, in <module>
    p.not_yes()
  File "C:\Users\Desktop\p.py", line 51, in <lambda>
    extended_dict["not_" + k] = lambda s, *args, **kw:  not v(s, *args, **kw)
TypeError: __init__() takes exactly 2 positional arguments (1 given)
>>>p.maybe(True)
True
>>>p.not_maybe(True)     #should be False
True

3 个回答

0

是的:

#lambda function with *args

l1=[1,2,3,4]
l2=(1,2,3,4)

val=lambda *args : sum(args )


val(*l1,*l2)
38

是的。

>>> l = lambda *x: print(x)
>>> l(1,2,3)
(1, 2, 3)
42

在使用lambda函数时,使用可变参数(varargs)是没有问题的。这里的问题其实是另外一个:

问题在于,lambda函数引用了循环中的变量v。但是当lambda函数被调用时,v的值已经改变了,这样lambda就会调用错误的函数。这是你在循环中定义lambda时需要特别注意的事情。

你可以通过创建一个额外的函数来解决这个问题,这个函数会在一个闭包中保存v的值:

def create_not_function(v):
    return lambda s, *args, **kw:  not v(s, *args, **kw)

for (k, v) in _dict.items():
    if hasattr(v, '__call__'):
        extended_dict["not_" + k] = create_not_function(v)

撰写回答