当前位置 : 主页 > 手机开发 > 其它 >

继承自Parent类的孙子 – Python

来源:互联网 收集:自由互联 发布时间:2021-06-19
我正在学习所有关于 Python类的知识,并且我有很多理由可以覆盖. 我遇到了一个让我有点困惑的例子. 这些是父类 Class XClass YClass Z 儿童班是: Class A (X,Y)Class B (Y,Z) 孙子课是: Class M (A,
我正在学习所有关于 Python类的知识,并且我有很多理由可以覆盖.
我遇到了一个让我有点困惑的例子.

这些是父类

Class X
Class Y
Class Z

儿童班是:

Class A (X,Y)
Class B (Y,Z)

孙子课是:

Class M (A,B,Z)

M类是否通过继承B类继承Z类,或者这种结构的原因是什么? M级会忽略第二次Z类继承不会,或者我错过了什么?

Class M would just inherit the Class Z attributes twice (redundant) wouldn’t it be, or am I missing something?

不,没有“重复”属性,Python执行线性化,他们可以按照方法解决顺序(MRO),例如,解释here.但是你在这里添加Z到列表不会改变任何东西是正确的.

他们首先为父母建造MRO,所以:

MRO(X) = (X,object)
MRO(Y) = (Y,object)
MRO(Z) = (Z,object)

MRO(A) = (A,X,Y,object)
MRO(B) = (B,Y,Z,object)

然后他们通过合并为M构建MRO:

MRO(M) = (M,)+merge((A,X,Y,object),(B,Y,Z,object),(Z,object))
       = (M,A,X,B,Y,Z,object)

现在,每次调用方法时,Python都会首先检查属性是否在该对象的内部字典self .__ dict__中.如果没有,Python将遍历MRO并尝试查找具有该名称的属性.从找到它的那一刻起,它就会停止搜索.

最后,super()是一个代理对象,它执行相同的分辨率,但是在类的阶段在MRO中启动.所以在这种情况下,如果你有:

class B:

    def foo():
        super().bar()

你构造一个对象m = M()并调用m.foo()然后 – 如果调用B的foo(),super().bar将首先尝试在Y中找到一个条,如果失败,它将在Z中查找一个条形图,最后在对象中查找.

属性不会继承两次.如果添加如下属性:

self.qux = 1425

然后它被简单地添加到该对象的内部自我.__ dict__字典中.

然而,明确地陈述Z可能是有益的:如果B的设计者不确定Z是否是真正的要求.在这种情况下,如果B被改变,你肯定知道Z仍然会在MRO中.

网友评论