我有一个名为
USA
的子类,它有两个父类 A
和 B
父级都有一个名为 change_to_4
的方法,在 B init 中我调用该方法,但没有使用我在 A 中定义的 b 方法,它使用 change_to_4
方法的 A 定义
class A:
def __init__(self) -> None:
self.a = 1
super().__init__()
def change_to_4(self):
self.x = 4
class B:
def __init__(self) -> None:
self.b = 2
self.change_to_4()
super().__init__()
def change_to_4(self):
self.b = 4
class USA(A, B):
def __init__(self) -> None:
super().__init__()
print(f"A vars = {vars(A())}")
print(f"B vars = {vars(B())}")
print(f"USA vars = {vars(USA())}")
print(f"USA mro -> {USA.__mro__}")
我期待这样的事情
A vars = {'a': 1}
B vars = {'b': 4}
USA vars = {'a': 1, 'b': 4}
USA mro -> (<class '__main__.USA'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
但是输出是
A vars = {'a': 1}
B vars = {'b': 4}
USA vars = {'a': 1, 'b': 2, 'x': 4}
USA mro -> (<class '__main__.USA'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
当解释器尝试查找实例的属性时,在本例中是在
self.change_to_4
的实例上查找 USA
,它首先尝试在 'change_to_4'
中查找 self.__dict__
,但未能在那里找到它,解释器然后按照 USA
的方法解析顺序(USA
、A
、B
、object
,如输出所示)在定义了它的第一个基本案例类中查找 change_to_4
属性。
摘自自定义类的文档:
类属性引用在此被转换为查找 字典,例如,
被翻译为C.x
(尽管有 有许多挂钩,可以使用其他方式进行定位 属性)。当在那里找不到属性名称时,该属性 搜索在基类中继续。基类的搜索 使用 C3 方法解析顺序,即使在 存在“钻石”继承结构 通往共同祖先的多重继承路径。C.__dict__["x"]
所以在这种情况下,
A
是定义USA
的change_to_4
的第一个基类,因此self.change_to_4()
被转换为A.change_to_4(self)
,导致self.x = 4
被执行。