functools.partial以及它如何组成非关键字参数

时间:2014-02-11 21:14:22

标签: python closures decorator

我发现functools.partial有很多很好的用例。

但是,我发现需要定义我所谓的partial_right。它就像是偏袒的,但是将“非正式”与非“k”结合起来。

我的问题是......我需要partial_right,还是我错过了什么?我可以用partial()或其他技术实现我想要的东西。

functools.partial的实现类似于:

def partial(func, *args, **keywords):
    def newfunc(*fargs, **fkeywords):
        newkeywords = keywords.copy()
        newkeywords.update(fkeywords)
        return func(*(args + fargs), **newkeywords)
    ...

这是我的问题“(args + fargs)”的排序。这种排序对于某些目的来说非常好,但是我发现了我想要相反排序的时间:

def partial_right(func, *args, **keywords):
    def newfunc(*fargs, **fkeywords):
        ...
        return func(*(fargs + args), **newkeywords)
    ...

一个这样的用例是当代码通过该方法上的一些装饰器构建“动态”方法时。目前还不知道“自我”的价值:

 class SomeClass(object):
     @decorator(a_value, b_value)
     def my_method(self, a, b):
         ...

在我的用例中,除了'self'之外,my_method的所有参数都是已知的。因此,partial_right用于动态创建等同于:

的内容
  def my_method_dynamic(self):
     self.my_method(a_value, b_value)

3 个答案:

答案 0 :(得分:2)

对于您的特定用例,使用operator.methodcaller

可能更合适
import operator
my_method_dynamic = operator.methodcaller('my_method', a_value, b_value)
my_method_dynamic(obj) # calls obj.my_method(a_value, b_value)

答案 1 :(得分:0)

最简单的解决方案是仅使用kwargs并为其赋予占位符值。这样,您就可以按照您想要的顺序指定所需的参数。

def my_method_dynamic(self, a=None, b=None):
  #do some stuff

partial_func = partial( my_method_dynamic, a=200, b=400)
#returns a thunk that still takes the desired argument

答案 2 :(得分:0)

不确定您的用例是什么,但您也可以这样做,这对您的用例来说可能更容易......

class MC2(object):
     def __init__(self):
         self.f2 = partial(self.f1, 4, 6)

     def f1(self, a, b):
         print a,b

这不适用于类,但self.f1似乎是一个闭包本身,self已绑定,因此它适用于实例。显然这对装饰器也不起作用,因为它们是在定义类时处理的。