python – 如何修补`__call__`方法?

前端之家收集整理的这篇文章主要介绍了python – 如何修补`__call__`方法?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我似乎无法修补类实例的__call__方法(是的,我想修补单个实例,而不是所有实例).

以下代码

@H_404_4@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())

输出

@H_404_4@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

虽然我想输出

@H_404_4@... example Explicit call: example test

我如何monkeypatch __call __()?为什么我不能像修补其他方法那样修补它?

虽然this answer告诉我们该怎么做(据说,我还没有测试过),但它没有解释为什么这个问题的部分原因.

解决方法

所以,正如 J.J. Hakala评论的那样,Python真正做的是调用: @H_404_4@type(a).__call__(a)

因此,如果我想覆盖__call__方法,我必须覆盖类的__call__,但如果我不想影响同一个类的其他实例的行为,我需要使用override__call__创建一个新类.方法.

所以如何覆盖__call__的示例如下所示:

@H_404_4@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)))

运行它会产生以下输出

@H_404_4@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
原文链接:https://www.f2er.com/python/185593.html

猜你在找的Python相关文章