假设有一个简单的多重继承设置,有两个基类A
和B
以及一个继承自两者的子类C
。
class A:
def __init__(self):
print("Started A's constructor")
# -- Not calling: super().__init__() --
print("Ended A's constructor")
class B:
def __init__(self):
print("Started B's constructor")
super().__init__()
print("Ended B's constructor")
class C(A, B):
def __init__(self):
print("Started C's constructor")
super().__init__()
print("Ended C's constructor")
打电话
c = C()
我们得到了输出
Started C's constructor
Started A's constructor
Ended A's constructor
Ended C's constructor
如果我想为每个C
对象调用两个基类构造函数,并且无法访问基类来添加super().__init__()
调用,那么应该更改或添加到C
?有没有办法这样做,如果A
确实调用super().__init__()
它不会破坏? (编辑:要清楚,将super().__init__()
添加到A
会调用B
的构造函数,因为它是MRO中的下一个;为了使它更清晰:code example)
更重要的是,在一般情况下,人们想要调用每个祖先的每个__init__
方法一次,并且不确定每个__init__
函数是否称为super().__init__()
,如何确保每个父类被调用一次且仅一次?
如果这是不可能的,这不会破坏基本的面向对象原则吗?简单地说,在这种情况下,A
的实现不应该影响B
的行为。
A
不使用super
,因此它不能用于合作继承。相反,根据A
为Python's super()
considered super!定义一个包装器。 (假设你不能简单地修复A
。)
class A:
def __init__(self):
print("Started A's constructor")
print("Ended A's constructor")
# AWrapper also needs to override each method defined by A;
# those simply delegate their work to the intenral instance of A
# For example,
#
# def some_method(self, x, y):
# return self.a.some_method(x, y)
#
class AWrapper:
def __init__(self, **kwargs):
self.a = A()
super().__init__(**kwargs)
class B:
...
class C(AWrapper, B):
...
您可以遍历类对象的__bases__
属性来调用每个父类的__init__
方法:
class C(A, B):
def __init__(self):
print("Started C's constructor")
for base in self.__class__.__bases__:
base.__init__(self)
print("Ended C's constructor")
所以C()
输出:
Started C's constructor
Started A's constructor
Ended A's constructor
Started B's constructor
Ended B's constructor
Ended C's constructor