Python super()函数机制详解:MRO顺序与多继承调用逻辑
本文深入解析Python中super()函数的执行机制,重点探讨多继承场景下的方法解析顺序(MRO)。通过三个典型案例,展示如何因调用super()时未指定类参数导致AttributeError,以及如何通过super(类名, self)精确控制搜索起点。文章结合Person3与D类的继承结构,详细演示了__mro__属性在确定父类调用路径中的核心作用,帮助开发者避免多继承中的常见陷阱。
首先来看第一个案例,分析以下代码的执行结果。
class Person:
def run(self):
print('studying')
class Person1:
def run(self):
print('working')
class Person2:
def run(self):
print('playing')
class Person3(Person,Person1,Person2):
def run(self):
super().run1()
p=Person3()
p.run()
实际运行后输出的结果为:
AttributeError: ‘super’ object has no attribute ‘run1’
这里需要特别注意以下几点:
1、当一个类继承多个父类时,若当前类中未定义该方法,Python会依据__mro__属性沿继承链向上逐一搜索。如果一直搜索到object类仍未找到该方法,程序将抛出AttributeError异常。
接着看第二个案例,分析以下代码的执行结果。
class Person:
def run(self):
print('studying')
class Person1:
def run(self):
print('working')
class Person2:
def run(self):
print('playing')
class Person3(Person,Person1,Person2):
def run(self):
super(Person1,self).run()
p=Person3()
p.run()
最终输出结果为:playing;而非working。
对此现象需注意:
1、关于super()函数的具体使用方式。调用super()时,可以通过super(类名, self)的形式明确指定从哪个类开始向上搜索父类方法。例如:super(Person1, self).run()表示以Person1类为起点,在self(即Person3的实例)的继承链中向上查找run方法。在Person1的MRO中,后续找到了<class ‘main.Person2’>,因此最终执行了Person2中的run方法,输出playing。
2、通过print(Person3.mro)可查看具体的继承顺序,结果为:(<class ‘main.Person3’>, <class ‘main.Person’>, <class ‘main.Person1’>, <class ‘main.Person2’>, <class ‘object’>)。
再看案例三,这是一个更复杂的继承结构,其原理与前两个案例相同。
class A:
def who(self):
print('A', end='')
class B(A):
def who(self):
super(B, self).who()
print('B', end='')
class C(A):
def who(self):
super(C, self).who()
print('C', end='')
class D(B, C):
def who(self):
super(D, self).who()
print('D', end='')
item = D()
item.who()
print(D.__mro__)
代码运行后的输出结果如下:
ACBD (<class ‘main.D’>, <class ‘main.B’>, <class ‘main.C’>, <class ‘main.A’>, <class ‘object’>)
总结
至此,关于Python中super()函数的疑问已解答完毕。如需了解更多相关Python super()函数的内容,欢迎搜索本站历史文章或继续阅读后续相关教程,感谢大家的支持!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









