我试图从导入的包中对SomeClass
上的方法进行monkeypatch:
from somepackage import SomeClass
def newmethod(obj, node, **kwargs):
""" """
SomeClass.oldmethod = newmethod
obj
和node
位于SomeClass.oldmethod
的默认呼叫签名中的位置:
class SomeClass(object):
def oldmethod(obj, node):
""" """
我知道monkeypatching不是一个好习惯,但我们需要一个解决方法,同时我们解决一些本来无法解决的问题。上述方法有效,但我们希望使用部分函数来完成此操作。例如:
from functools import partial
newmethod_a = partial(newmethod, foo='a')
newmethod_b = partial(newmethod, foo='b')
正在调用部分函数,因为我们需要传递不同的** kwargs。但是当我现在尝试超载时:
SomeClass.oldmethod = newmethod_a
我收到与传递的参数数量相关的错误,但它对我的问题非常具体,所以粘贴它可能没有帮助......我认为错误与{{1的调用签名有关取两个位置参数(oldmethod
),我的部分函数没有正确地传递对obj, node
和obj
的引用。我尝试了不同的结构,如:
node
对不起,我无法提供最小的工作示例。我希望也许专家会从经验中认识到这个问题,并告诉我在newmethod_a = partial(SomeClass.newmethod, foo='a')
范围内我是否有可能尝试的是什么。
由于
答案 0 :(得分:12)
这是一个简单的例子:
from functools import partial
class foo(object):
def bar(self, pos1, **kwargs):
print("bar got self=%r, pos1=%r, kwargs=%r" % (self, pos1, kwargs))
foo.bar = partial(foo.bar, qux=1)
baz = foo()
baz.bar(1) # Fails...
这失败了TypeError
。原因是baz.bar
是一个绑定方法,它希望它的第一个参数是foo
实例,但partial
对象不是,因此Python不会添加{{ 1}}给你打电话self
。 (这不完全正确,但真正的原因是非常技术性的。请参阅下面描述的描述符方法。)调用baz.bar
将起作用。要解决此问题,您必须再次baz.bar(baz, 1)
方法:
foo.bar
另见:
答案 1 :(得分:1)
替换:
newmethod_a = functools.partial(newmethod, foo='a')
使用:
def newmethod_a(obj, node, **kwargs):
kwargs.update({"foo": "a"})
return newmethod(obj, node, **kwargs)