【发布时间】:2019-07-27 12:51:41
【问题描述】:
假设有一个简单的多重继承设置,有两个基类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 的行为。
【问题讨论】:
-
你不应该在
B.__init__中调用super。您只需拨打__init__的object即可。 -
如果开发人员不打算让人们调用它,为什么不选择
object的__init__不做任何事情?您是否有任何参考或进一步了解为什么永远不应该调用它,并且不会在任何 python 库中调用它?这样的答案可能比评论更适合作为答案。 -
要使用协作多重继承和
super,那么每个类都需要调用super。拨打super().__init__()A.__init__ -
@PaulRooney 不,它不是这样工作的。您需要在
B和A中调用super以获取完整的 MRO 链。 super 并不意味着调用直接父类。这意味着在 MRO 中调用下一个。如果您的类要使用协作多重继承,则需要调用super -
@PaulRooney:当你构造一个
B时,超级调用只是调用object.__init__。在多重继承的情况下,这就是这个问题的重点,超级调用可能会调用不同的__init__而不是object.__init__。
标签: python python-3.x oop multiple-inheritance