问题 使用部分函数修补猴子[重复]


这个问题在这里已有答案:


3774
2018-01-28 05:34


起源

请至少说明您所获得的错误文本,然后将明确@Philips是否以正确的方向回答点,或者还有其他内容。可能性是无止境... - knitti
你的问题实际上是重复的 类方法的functools.partial;我现在就让你付出赏金。 - Martijn Pieters♦
我在4个月前问过这个问题,我真的没有环境来测试解决方案了。提供的答案似乎很好。虽然我没有把赏金给予 - Adam Hughes
@MartijnPieters这是我的赏金。我没有在classmethod问题上找到functools.partial,但它看起来也很相关。 - Rick Teachey
@MartijnPieters另外,有趣的是,这个问题实际上比那个问题还要老,尽管直到今天它还没有任何答案! - Rick Teachey


答案:


这是一个简单的例子:

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 是一个绑定方法,它期望它的第一个参数是a foo 例如,但是那个 partial 对象不是,因此Python不会添加 self 给你打电话的时候 baz.bar。 (这不完全正确,但真正的原因是非常技术性的。请参阅下面描述的描述符方法。)调用 baz.bar(baz, 1) 会工作。要解决这个问题,你必须要做 foo.bar 再一个方法:

import types

# In Python 2:
foo.bar = types.MethodType(partial(foo.bar.__func__, qux=1), None, foo)
# Method that is compatible with both Python 2 and 3:
foo.bar = types.MethodType(partial(foo.bar, qux=1), foo)
# Python 3 only:
from functools import partialmethod
foo.bar = partialmethod(foo.bar, qux=1)

baz = foo()
baz.bar(1) # Works!

也可以看看:


12
2018-05-28 07:15



太好了,谢谢 - Adam Hughes
在Python 3中,使用 functools.partialmethod();它专为此用例而设计。 - Martijn Pieters♦
谢谢,我补充说,并链接到另一个问题。 - Phillip


更换:

newmethod_a = functools.partial(newmethod, foo='a')

有:

def newmethod_a(obj, node, **kwargs):
    kwargs.update({"foo": "a"})
    return newmethod(obj, node, **kwargs)

1
2018-05-28 07:37