python多重继承:避免以菱形形状两次调用构造函数 [英] python multiple inheritance: avoid calling the constructors twice in diamond shape

查看:200
本文介绍了python多重继承:避免以菱形形状两次调用构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下代码:

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

据我了解,算法如下:

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__

实际上有三个问题:
1.为什么当selfD的实例时,为什么super().__init__()调用B.__init__(在2)会调用C.__init__? 2.在这种情况下,如何避免两次调用C.__init__A.__init__? 2.1初始化当前类继承的所有类的正确方法是什么?

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:当self是D的实例时,为什么B.__init__(在2)处的super().__init__()调用会调用C.__init__? >

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

致电时

super(X, self).__init__

Python查找 MRO self.__class__.mro() .然后,它会在X之后从MRO中的 next 类调用__init__.

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

当self是D的实例时,self.__class__.mro()[D, B, C, A].因此super(B, self).__init__()调用C.__init__(self).

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

问:初始化当前类继承的所有类的正确方法是什么?

还要在D.__init__中使用超级:

class D(B, C):
    def __init__(self):
        print("D.__init__")
        super(D, self).__init__()
        print("D.__init__ finished")

这篇关于python多重继承:避免以菱形形状两次调用构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆