【问题标题】:varargs in lambda functions in PythonPython中的lambda函数中的可变参数
【发布时间】:2010-05-26 16:26:29
【问题描述】:

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

【问题讨论】:

    标签: python lambda variadic-functions


    【解决方案1】:

    在 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)
    

    【讨论】:

      【解决方案2】:

      是的。

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

      【讨论】:

      • 请注意,这只适用于 Python3。 Python2 不支持此语法。
      • 更准确地说,lambda *x: 可以在 Python 2 中使用,但 print 在 lambda 中只能在 Python 3 中使用。
      • 请注意,在print(x) 中,它会将参数打印为元组,而print(*x) 将调用 print 并解包参数。
      猜你喜欢
      • 2016-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-09
      • 2017-06-12
      • 1970-01-01
      相关资源
      最近更新 更多