我想对于Python专家来说这是一个简单的...但也许有人可以解释我。
想象我们有两个具有相同字段的类:
class A:
name = 'a'
class B:
name = 'b'
现在我们有了第三个类,它继承了这两个类:
class C(A, B):
...
现在我们可以用
C.name
检查名称字段,我发现字段值为 'a'
。
我可以假设“获胜”的总是第一类吗?第二个类不应该覆盖第一个字段吗?
在Python中,当一个类继承多个父类时,继承的顺序决定了属性查找的解析顺序。在类 C 继承自类 A 和 B 的情况下,属性查找遵循称为方法解析顺序 (MRO) 的特定顺序。
MRO 决定了 Python 在父类中查找属性的顺序。它使用深度优先、从左到右的算法,称为 C3 线性化。在此算法中,继承声明中列出的第一个父类具有更高的优先级。
在您的示例中,由于在类 C (
class C(A, B)
) 的继承声明中,类 A 在类 B 之前列出,因此 name
的属性查找将首先在类 A 中找到它。如果 A 类没有定义 name
属性,那么它将在 B 类中查找。
如果要颠倒继承顺序 (
class C(B, A)
),则 name
的属性查找将首先在类 B 中找到它。在这种情况下,B 类将“获胜”并覆盖 A 类中定义的值。
要查看类的 MRO,可以使用内置
__mro__
属性或 mro()
方法。例如,C.__mro__
将为您提供类C的MRO元组,它表示属性查找的顺序。
请记住,MRO 和属性查找行为可能会在不同版本的 Python 或不同的类层次结构中发生变化,因此明确并避免依赖继承顺序进行属性解析始终是一个好习惯。
Python 2 和 Python 3 之间的方法解析顺序 (MRO) 行为发生了变化。在 Python 2 中,MRO 顺序是稳定的,但在 Python 3 中由于采用了 C3 线性化算法而有所不同。我目前遇到与多重继承相关的问题,其中 MRO 确定多个类中字段的顺序,我正在积极寻求解决方案来解决此问题。