繁体   English   中英

Python:如何使用lambda或partial来绑定除第一个位置参数之外的参数

[英]Python: how to use lambda or partial to bind arguments other than the first positional argument

我在尝试使用lambdafunctools.partial创建一个具有来自现有函数的绑定位置参数的新函数时遇到了很多困惑。

我想做这样的事情(行为不符合要求):

def addFunction(self, name, in_function, secondary_args=None, secondary_kwargs=None):

        # Assign the function with optional args based on whether any
        # optional args are not None

        if secondary_args is not None and secondary_kwargs is not None:
            func = lambda x: in_function(x, *secondary_args, **secondary_kwargs)
        elif secondary_args is None and secondary_kwargs is not None:
            func = lambda x: in_function(x, **secondary_kwargs)
        elif secondary_args is not None and secondary_kwargs is None:
            func = lambda x: in_function(x, *secondary_args)
        else:
            func = in_function
        ###

        func.__doc__ = in_function.__doc__
        self[name] = func # <-- This method is a class method for something deriving dict.

我也尝试用等效的functools.partial语句替换所有lambda语句。

问题是如果我像这样使用这个函数:

# Assume some_function takes 3 arguments, a float, a Bool, and a String,
# in that order.

someObject.addFunction("my_f", some_function, secondary_args=[True, "Option_A"])

现在,当我尝试使用(仅举例) someObject["my_f"](5.0)它会在调试时报告第一个参数为True

看起来像绑定,无论是lambda还是partial只是简单地推入位置参数,或者只接受你在*args末尾的额外位置参数,否则只是放弃它(我不确定哪个)。

对于我的应用程序,由于许多函数将存储在这样的特定对象中,并且用户选择了不同数量的可选参数,因此使用绑定参数返回的函数仍然接受用户的参数作为第一个位置参数,而不是强制所有参数都是关键字参数。

这看起来应该很简单。 我错过了什么?

你能发布一个重现错误的完整脚本吗? 因为以下脚本按预期工作:

class C(dict):                                                               
    def addFunction(self, name, in_function, secondary_args=None, secondary_kwargs=None):

        # Assign the function with optional args based on whether any        
        # optional args are not None                                         

        if secondary_args is not None and secondary_kwargs is not None:      
            func = lambda x, *secondary: in_function(x, *secondary_args, **secondary_kwargs)
        elif secondary_args is None and secondary_kwargs is not None:        
            func = lambda x: in_function(x, **secondary_kwargs)              
        elif secondary_args is not None and secondary_kwargs is None:        
            func = lambda x: in_function(x, *secondary_args)                 
        else:                                                                
            func = in_function                                               
        ###                                                                  

        func.__doc__ = in_function.__doc__                                   
        self[name] = func  # <-- This method is a class method for something deriving dict.


def f(x, y=0, z=1):                                                          
    print x, y, z                                                            


c = C()                                                                      
c.addFunction('my_f', f, secondary_args=[-1])                                
c['my_f'](0)                                                                 

# output is 0 -1 1, as expected                                              

也许问题出在你如何将这个功能“附加”到你的对象上?

听起来你只想要一些自定义类型的函数包装器:

class Caller(object):

    def __init__(self, fn, *args, **kwargs):
        self._fn = fn
        self._args = args 
        self._kwargs = kwargs

    def __call__(self, *uargs, **ukwargs):
        arg = uargs + self._args
        kw =  dict(ukwargs.items() + self._kwargs.items())
        self._fn(*arg, **kw)

然后包装一些东西:

def test(a,b,c=None):
    print a,b,c

c = Caller(test, 2,c=True)
c(1)
# 1 2 True

我确信可以清理Caller ,但这只是如何存储原始fn和params的快速示例,然后控制它何时被调用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM