6

lambda在尝试使用 a或functools.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.

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

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

# 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我调试它时。

看起来绑定,无论是使用lambdapartial简单地推入位置参数,要么只在末尾接受你额外的位置参数,要么*args只是放弃它(我不确定是哪个)。

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

这似乎应该很简单。我错过了什么?

4

2 回答 2

1

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

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                                              

也许问题在于你如何将函数“附加”到你的对象上?

于 2012-08-06T16:13:26.600 回答
0

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

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 和参数,然后控制何时调用它。

于 2012-08-06T15:45:03.750 回答