Ily*_*hev 7 python inheritance monkeypatching
在阅读了有关 Python 中猴子修补类的问题的答案后,我尝试将建议的解决方案应用于以下情况。
假设我们有一个模块a.py
class A(object):
def foo(self):
print(1)
class AA(A):
pass
Run Code Online (Sandbox Code Playgroud)
让我们尝试按如下方式对其进行猴子修补。当我们猴子补丁类时它起作用A:
>>> import a
>>> class B(object):
... def foo(self):
... print(3)
...
>>> a.A = B
>>> x = a.A()
>>> x.foo()
3
Run Code Online (Sandbox Code Playgroud)
但是如果我们尝试继承的类,它就不会被修补:
>>> y = a.AA()
>>> y.foo()
1
Run Code Online (Sandbox Code Playgroud)
有什么方法可以用所有继承的类来猴子修补该类吗?
编辑
目前,对我来说最好的解决方案如下:
>>> class AB(B, a.AA):
... pass
...
>>> a.AA = AB
>>> x = a.AA()
>>> x.foo()
3
Run Code Online (Sandbox Code Playgroud)
的任何复杂结构都将被继承,并且和a.AA之间的唯一区别是方法。这样,我们就不会修改任何内部类属性(如或)。唯一剩下的缺点是我们需要为每个继承的类执行此操作。ABa.AAfoo()__base____dict__
这是最好的方法吗?
您需要显式覆盖 中的基类元组a.AA,但我不建议像这样修改类。
>>> import a
>>> class B:
... def foo(self):
... print(2)
...
>>> a.AA.__bases__ = (B,)
>>> a.AA().foo()
2
Run Code Online (Sandbox Code Playgroud)
这也将反映在a.A.__subclasses__()(尽管我不完全确定它是如何工作的;事实上它是一种方法,表明它在运行时以某种方式计算它,而不是简单地返回由 的原始定义修改的值AA) 。
看来语句中的基类只是被记住,而不是被使用,直到某些操作需要它们为止(例如在属性查找期间)。可能还有一些其他微妙的极端情况没有顺利处理:caveatprogrammator。class