请问能解释一下输出顺序吗?
>>> class A:... def __init__(self):
... print("哈喽,我是A~")
...
>>> class B1(A):
... def __init__(self):
... super().__init__()
... print("哈喽,我是B1~")
...
>>> class B2(A):
... def __init__(self):
... super().__init__()
... print("哈喽,我是B2~")
...
>>> class C(B1, B2):
... def __init__(self):
... super().__init__()
... print("哈喽,我是C~")
...
>>> c = C()
哈喽,我是A~
哈喽,我是B2~
哈喽,我是B1~
哈喽,我是C~
代码与输出结果如上。对上面的输出结果不理解,请教各位。
我个人理解,输出结果顺序应该是
哈喽,我是A~
哈喽,我是B1~
哈喽,我是B2~
哈喽,我是C~
这个例子演示的是 Python 中的多重继承和方法解析顺序(Method Resolution Order, MRO)。多重继承是一种让一个类可以从多个父类继承属性和方法的能力。Python中的MRO则确定了子类继承父类时的调用顺序。
在Python中,MRO由一个特定的算法决定,叫做C3线性化或者也叫做查尔斯顺序(Charles's order)。这个算法确保了每个类都会先于其所有子类被访问,而且每个父类也会按照它们在列表中的顺序被访问。
在你给出的例子中,我们有四个类A,B1,B2和C。C是B1和B2的子类,B1和B2都是A的子类。根据C3线性化,其方法解析顺序为C -> B1 -> B2 -> A。
因此,在实例化C类时,会首先调用A的初始化方法,然后是B2的初始化方法,接着是B1的初始化方法,最后是C的初始化方法。所以输出的结果是:
哈喽,我是A~
哈喽,我是B2~
哈喽,我是B1~
哈喽,我是C~
这就是为什么在调用super().__init__()时会按照这个顺序打印出结果。 isdkz 发表于 2023-6-10 18:27
这个例子演示的是 Python 中的多重继承和方法解析顺序(Method Resolution Order, MRO)。多重继承是一种让一 ...
class A:
def __init__(self):
print("哈喽,我是A~")
class B1(A):
def __init__(self):
super().__init__()
print("哈喽,我是B1~")
class B2:
def __init__(self):
super().__init__()
print("哈喽,我是B2~")
class C(B1, B2):
def __init__(self):
super().__init__()
print("哈喽,我是C~")
c = C()
哈喽,我是A~
哈喽,我是B1~
哈喽,我是C~
非常感谢您的指点,我向多问一句,上面这个代码解析方法是什么啊?(按照您的分析思路,是不是应该是C -> B1 -> A ->B2)
为什么“哈喽,我是B2~"没有打印出来呢? wbzxz 发表于 2023-6-10 21:45
非常感谢您的指点,我向多问一句,上面这个代码解析方法是什么啊?(按照您的分析思路,是不是应该 ...
你的观察很好!在你的第二个代码片段中,注意到B2类的 __init__ 方法调用了 super().__init__() ,但是B2类并没有明确指定父类。在Python中,如果类定义时没有指定父类,则默认的父类是object类,object是所有Python类的最基本的类。
在这个情况下,当B2的 __init__ 方法执行 super().__init__() 时,它实际上是调用了object类的 __init__ 方法,而不是A类的 __init__ 方法。因此,A类的 __init__ 方法在B1中被调用,然后直接跳过了B2,所以并没有打印“哈喽,我是B2~”。
所以,初始化C类的解析顺序为C -> B1 -> A。这就解释了为什么“哈喽,我是B2~"没有被打印出来。
如果你希望在初始化C类时同时调用B2的初始化方法,那么你需要让B2类也继承自A类或者其它具有 __init__ 方法的类。这样在执行 super().__init__() 时就会调用那个类的 __init__ 方法。
页:
[1]