Python 多重继承中基类的顺序和super()用法
你能帮我理解这两种情况的区别吗Python 多重继承中基类的顺序和super()用法,python,python-3.x,multiple-inheritance,super,Python,Python 3.x,Multiple Inheritance,Super,你能帮我理解这两种情况的区别吗 class B1: def f(self): super().temp() class B2: def temp(self): print("B2") class A(B1, B2): pass A().f() 它打印“B2” 如果我们切换B1和B2: class A(B2, B1): pass A().f() 我得到AttributeError:“super”对象没有属性“temp”Py
class B1:
def f(self):
super().temp()
class B2:
def temp(self):
print("B2")
class A(B1, B2):
pass
A().f()
它打印“B2”
如果我们切换B1
和B2
:
class A(B2, B1):
pass
A().f()
我得到
AttributeError:“super”对象没有属性“temp”
Python使用调用的东西来决定基类的顺序:“方法解析顺序”。非正式地说,这基本上有两部分:
- 路径必须是层次结构,不能从一个类向下到它的超类,即使是间接的。因此,不允许循环,
意味着issubclass(X,Y)和issubclass(Y,Z)
issubclass(X,Z)
- 在不受上述规则强制的情况下,顺序是按最高级类的步数排序(较低的步数表示链中的较早),然后是类列表中类的顺序(列表中的较早者表示链中的较早者)
A
/ \
/ \
B1 B2 # Possibly switched
\ /
\ /
object
在第一种情况下,C3线性化后的顺序为
super super super
A → B1 → B2 → object
我们可以通过以下方式了解:
A.mro()
#>>> [<class 'A'>, <class 'B1'>, <class 'B2'>, <class 'object'>]
因此调用A().f()
尝试:
- 实例上是否有
?没有,所以f
在头等舱吗,f
?没有,所以A
是否在下一节课上,f
?对!李>B1
B1.f
,调用B2.temp(self)
,检查:
在班上吗,f
?对!李>B2
B2
在第二种情况下,我们有
super super super
A → B2 → B1 → object
因此,问题解决了
因此,super()
调用将解析为:
class A(B1, B2):
pass
class B1:
def f(self):
# super() proxies the next link in the chain,
# which is B2. It implicitly passes self along.
B2.temp(self)
class B2:
def temp(self):
print("B2")
class A(B2, B2):
pass
class B2:
def temp(self):
print("B2")
class B1:
def f(self):
# super() proxies the next link in the chain,
# which is B2. It implicitly passes self along.
object.temp(self)
- 实例上是否有
?没有,所以f
在头等舱吗,f
?没有,所以A
是否在下一节课上,f
?没有,所以B2
是否在下一节课上,f
?对!李>B1
B1.f
,并调用object.temp(self)
,检查:
是否在类的f
对象上?不,
- 没有超类,因此我们无法找到该属性
- Raise
AttributeError(“{!r}对象没有属性{!r}”。格式(实例,属性\名称))
A的MRO中的类顺序:
class A1(B1, B2):
pass
class A2(B2, B1):
pass
print(A1.mro())
print(A2.mro())
返回:
[<class '__main__.A1'>, <class '__main__.B1'>, <class '__main__.B2'>, <class 'object'>]
[,]
及
[,]
现在,当您调用A1.f()
或A2.f()
时,该属性在B1
中找到,并且在那里您调用super().temp()
,这意味着在MRO
中找到下一个类时调用temp()
(或者在未找到temp
之前移动到它旁边的类,依此类推)
由于A2
的下一个也是唯一一个类是object
,它没有temp()
方法,因此引发了一个错误
如果A1
在B1
之后的下一个类是B2
,它有一个temp()
方法,因此不会产生错误 什么让你困惑B2
没有实现f
,因此如果先在那里查找它(在第二种情况下),就找不到它。我猜OP不理解为什么类A的参数顺序在这里很重要,或者顺序有什么影响。
[<class '__main__.A2'>, <class '__main__.B2'>, <class '__main__.B1'>, <class 'object'>]