我发现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)
答案 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
已绑定,因此它适用于实例。显然这对装饰器也不起作用,因为它们是在定义类时处理的。