我似乎无法猴子修补类实例的__call__
方法(是的,我只想修补单个实例,而不是全部实例)。
如下代码:
class A(object):
def test(self):
return "TEST"
def __call__(self):
return "EXAMPLE"
a = A()
print("call method: {0}".format(a.__call__))
print("test method: {0}".format(a.test))
a.__call__ = lambda : "example"
a.test = lambda : "test"
print("call method: {0}".format(a.__call__))
print("test method: {0}".format(a.test))
print(a())
print("Explicit call: {0}".format(a.__call__()))
print(a.test())
输出此:
call method: <bound method A.__call__ of <__main__.A object at 0x7f3f2d60b6a0>>
test method: <bound method A.test of <__main__.A object at 0x7f3f2d60b6a0>>
call method: <function <lambda> at 0x7f3f2ef4ef28>
test method: <function <lambda> at 0x7f3f2d5f8f28>
EXAMPLE
Explicit call: example
test
虽然我希望它输出:
...
example
Explicit call: example
test
如何猴子补丁
__call__()
?为什么我不能像修补其他方法一样修补它? 尽管this answer告诉了如何做(据说,我还没有测试过),但是它没有解释问题的原因。
最佳答案
因此,正如J.J. Hakala所评论的那样,Python的真正作用是调用:
type(a).__call__(a)
这样,如果我想覆盖
__call__
方法,我必须覆盖类的__call__
,但是如果我不想影响同一类的其他实例的行为,则需要使用覆盖的__call__
方法。因此,如何覆盖
__call__
的示例如下所示:class A(object):
def test(self):
return "TEST"
def __call__(self):
return "EXAMPLE"
def patch_call(instance, func):
class _(type(instance)):
def __call__(self, *arg, **kwarg):
return func(*arg, **kwarg)
instance.__class__ = _
a = A()
print("call method: {0}".format(a.__call__))
print("test method: {0}".format(a.test))
patch_call(a, lambda : "example")
a.test = lambda : "test"
print("call method: {0}".format(a.__call__))
print("test method: {0}".format(a.test))
print("{0}".format(a()))
print("Explicit a.__call__: {0}".format(a.__call__()))
print("{0}".format(a.test()))
print("Check instance of a: {0}".format(isinstance(a, A)))
运行它会产生以下输出:
call method: <bound method A.__call__ of <__main__.A object at 0x7f404217a5f8>>
test method: <bound method A.test of <__main__.A object at 0x7f404217a5f8>>
call method: <bound method patch_call.<locals>._.__call__ of <__main__.patch_call.<locals>._ object at 0x7f404217a5f8>>
test method: <function <lambda> at 0x7f404216d048>
example
Explicit a.__call__: example
test
Check instance of a: True
关于python - 如何猴子修补 `__call__`方法?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38541015/