Python中的lambda函数中的varargs [英] varargs in lambda functions in Python

查看:72
本文介绍了Python中的lambda函数中的varargs的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

lambda函数是否可能具有可变数量的参数? 例如,我想编写一个元类,它为某些其他类的每个方法创建一个方法,而这个新创建的方法返回与原始方法相反的值,并且具有相同数量的参数. 我想用lambda函数做到这一点.如何传递参数?有可能吗?

Is it possible a lambda function to have variable number of arguments? For example, I want to write a metaclass, which creates a method for every method of some other class and this newly created method returns the opposite value of the original method and has the same number of arguments. And I want to do this with lambda function. How to pass the arguments? Is it possible?

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

但是结果是完全错误的:

But the result is totally wrong:

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

推荐答案

在lambda函数中使用varargs没问题.这里的问题是不同的:

There is no problem using varargs in lambda functions. The issue here is different:

问题在于lambda引用了循环变量v.但是,在调用lambda时,v的值已更改,并且lambda调用了错误的函数.在循环中定义lambda时,始终要注意这一点.

The problem is that the the lambda refrences the loop variable v. But by the time the lambda is called, the value of v has changed and the lambda calls the wrong function. This is always something to watch out for when you define a lambda in a loop.

您可以通过创建一个附加函数来解决此问题,该函数将在闭包中保存v的值:

You can fix this by creating an additional function which will hold the value of v in a closure:

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)

这篇关于Python中的lambda函数中的varargs的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆