在 Python 中继承 classes 的猴子修补 class

Monkey-patching class with inherited classes in Python

阅读 the question about monkey-patching classes in Python 的答案后,我尝试将建议的解决方案应用于以下案例。

假设我们有一个模块a.py

class A(object):
    def foo(self):
        print(1)

class AA(A):
    pass

让我们尝试按如下方式对其进行猴子修补。当我们猴子补丁 class A:

>>> import a
>>> class B(object):
...     def foo(self):
...             print(3)
... 
>>> a.A = B
>>> x = a.A()
>>> x.foo()
3

但是如果我们尝试继承的class,它会变成没有打补丁:

>>> y = a.AA()
>>> y.foo()
1

有没有办法用猴子修补 class 及其所有继承的 classes?

编辑

目前,对我来说最好的解决方案如下:

>>> class AB(B, a.AA):
...     pass
... 
>>> a.AA = AB
>>> x = a.AA()
>>> x.foo()
3

a.AA 的任何复杂结构都将被继承,ABa.AA 之间的唯一区别是 foo() 方法。这样,我们不会修改任何内部 class 属性(如 __base____dict__)。唯一剩下的缺点是我们需要为每个继承的 classes.

这样做

这是最好的方法吗?

你需要在a.AA中显式地覆盖基类的元组,但我不建议像这样修改类。

>>> import a
>>> class B:
...   def foo(self):
...     print(2)
...
>>> a.AA.__bases__ = (B,)
>>> a.AA().foo()
2

这也将反映在 a.A.__subclasses__() 中(尽管我不完全确定 如何 起作用;它是一种方法这一事实表明它计算这在运行时以某种方式进行,而不是简单地返回由 AA).

的原始定义修改的值

似乎 class 语句中的碱基 类 被简单地记住了,而不是 使用了 ,直到某些操作需要它们(例如在属性查找期间)。可能还有一些其他微妙的角落情况没有顺利处理:caveat programmator.