Python lambda 函数中的可变参数

新手上路,请多包涵

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

原文由 brain_damage 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 799
2 个回答

在 lambda 函数中使用可变参数没有问题。这里的问题是不同的:

问题是 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)

原文由 interjay 发布,翻译遵循 CC BY-SA 2.5 许可协议

是的。

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

原文由 Joe Koberg 发布,翻译遵循 CC BY-SA 2.5 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题