继承顺序的逻辑是非常重要的,它决定了在使用子类的属性和方法时,Python 解释器的搜索顺序。
在 Python 中,当一个类继承自多个父类时,解释器会按照一定的顺序搜索属性和方法。这个搜索顺序被称为方法解析顺序(Method Resolution Order, MRO)。
假设我们有以下三个类:
class A:
def __init__(self):
self.a = 1
def foo(self):
print("A's foo")
class B(A):
def __init__(self):
super().__init__()
self.b = 2
def foo(self):
print("B's foo")
class C(A):
def __init__(self):
super().__init__()
self.c = 3
def foo(self):
print("C's foo")
class D(B, C):
def __init__(self):
super().__init__()
self.d = 4
def foo(self):
print("D's foo")
在这个例子中:
A
是一个基类,定义了__init__
方法和foo
方法。B
和C
都继承自A
,并且都重写了foo
方法。D
同时继承自B
和C
,并且也重写了foo
方法。
现在,让我们创建一个 D
类的实例,并调用它的 foo
方法:
d = D()
d.foo()
输出结果为:
B's foo
这是因为 Python 的继承顺序遵循深度优先、从左到右的原则。具体的搜索顺序如下:
D
B
A
C
当调用 d.foo()
时,Python 首先在 D
类中查找 foo
方法,发现有定义,于是执行 D
类中的 foo
方法。
如果我们调换 B
和 C
在 D
类中的继承顺序:
class D(C, B):
def __init__(self):
super().__init__()
self.d = 4
def foo(self):
print("D's foo")
此时,输出结果为:
C's foo
这是因为 Python 的搜索顺序变成了:
D
C
A
B
所以,在调用 d.foo()
时,Python 会先在 D
类中查找 foo
方法,发现没有定义,然后按照 MRO 顺序在 C
类中找到并执行 foo
方法。
总的来说,继承顺序的逻辑是:
- 深度优先:先搜索子类,再搜索父类。
- 从左到右:当一个类有多个父类时,按照从左到右的顺序搜索。
这个搜索顺序可以通过 __mro__
属性或 mro()
方法查看。例如:
print(D.__mro__)
# (<class '__main__.D'>, <class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
理解好继承顺序的逻辑,可以帮助