python多重继承初始化,python多重继承:避免以菱形形状两次调用构造函数

Consider the following code:

class A(object):

def __init__(self):

print("A.__init__")

super(A, self).__init__() # 1

print("A.__init__ finished")

class B(A):

def __init__(self):

print("B.__init__")

super(B, self).__init__() # 2

print("B.__init__ finished")

class C(A):

def __init__(self):

print("C.__init__")

super(C, self).__init__()

print("C.__init__ finished")

class D(B, C):

def __init__(self):

print("D.__init__")

print("Initializing B")

B.__init__(self) # 3

print("B initialized")

print("Initializing C")

C.__init__(self) # 4

print("C initialized")

print("D.__init__ finished")

D()

# D.__init__

# Initializing B

# B.__init__

# C.__init__

# A.__init__

# A.__init__ finished

# C.__init__ finished

# B.__init__ finished

# B initialized

# Initializing C

# C.__init__

# A.__init__

# A.__init__ finished

# C.__init__ finished

# C initialized

# D.__init__ finished

As far as I understand, the algorithm is as follows:

D.__init__ at (3) -> B.__init__ ->

-> super().__init__ -> (super of self.__class__).__init__ ->

-> C.__init__ (# why C?) -> super().__init__ ->

-> A.__init__

D.__init__ at (4) -> C.__init__ ->

-> super().__init__ ->

-> A.__init__

Actually there are three questions:

1. Why super().__init__() call in B.__init__ (at 2) calls C.__init__ when self is an instance of D?

2. How to avoid calling C.__init__ and A.__init__ twice in this case?

2.1 What is the right way to initialize all the classes the current class inherits from?

解决方案

Q: Why super().__init__() call in B.__init__ (at 2) calls C.__init__ when self is an instance of D?

When you call

super(X, self).__init__

Python looks up the MRO self.__class__.mro(). It then calls __init__ from the next class in the MRO after X.

When self is an instance of D, self.__class__.mro() is [D, B, C, A]. So super(B, self).__init__() calls C.__init__(self).

Q: What is the right way to initialize all the classes the current class inherits from?

Use super in D.__init__ as well:

class D(B, C):

def __init__(self):

print("D.__init__")

super(D, self).__init__()

print("D.__init__ finished")

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值