我有一个名为USA的子类,它有两个父类AB. 两个父对象都有一个名为change_to_4的方法,在B.__init__中我调用了该方法,但它没有使用我在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'>)

但yields

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'>)

推荐答案

当解释器查找实例的属性时(在本例中是在USA的实例上查找self.change_to_4),它首先try 在self.__dict__中查找'change_to_4',但在那里找不到它,然后解释器按照USA的方法解析顺序(如输出中所示的USAABobject)在定义了change_to_4属性的第一个基类中查找change_to_4属性.

摘自Custom classes人的文档:

类属性引用在此 字典,例如,C.x翻译成C.__dict__["x"](尽管有 是一些钩子,允许其他定位方式, 属性).如果在此处找不到属性名称,则属性 在基类中继续搜索.这种对基类的搜索 使用C3方法解析顺序,即使在 存在"钻石"遗传 struct , 多条遗传路径可以追溯到共同的祖先.

在本例中,A是定义change_to_4USA的第一个基类,因此self.change_to_4()被转换为A.change_to_4(self),导致self.x = 4被执行.

调用self.change_to_4()是从B中的方法进行的这一事实不会改变在USA实例的方法解析顺序中AB之前的事实.

Python相关问答推荐

两极按组颠倒顺序

在Python中是否可以输入使用任意大小参数列表的第一个元素的函数

使用Python进行网页抓取,没有页面

如何才能将每个组比上一组增加N %?

单击Python中的复选框后抓取数据

socket.gaierror:[Errno -2]名称或服务未知|Firebase x Raspberry Pi

实现的差异取决于计算出的表达是直接返回还是首先存储在变量中然后返回

使用from_pandas将GeDataFrame转换为polars失败,ArrowType错误:未传递numpy. dype对象

Pandas :多索引组

由于NEP 50,向uint 8添加-256的代码是否会在numpy 2中失败?

Pytest两个具有无限循环和await命令的Deliverc函数

2D空间中的反旋算法

根据二元组列表在pandas中创建新列

将输入聚合到统一词典中

改进大型数据集的框架性能

Plotly Dash Creating Interactive Graph下拉列表

如何禁用FastAPI应用程序的Swagger UI autodoc中的application/json?

lityter不让我输入左边的方括号,'

将标签移动到matplotlib饼图中楔形块的开始处

使用Openpyxl从Excel中的折线图更改图表样式