Python多重继承的查找顺序:经典类与新式类深度解析

咖啡半糖
咖啡半糖
发布时间:2026-10-13 | 3人浏览过
原创

本文详细解析Python中多重继承的属性查找顺序。通过对比经典类与新式类的实现,指出经典类采用“从左至右、深度优先”策略,而新式类采用“广度优先”策略。文章结合具体代码示例与MRO(Method Resolution Order)机制,帮助开发者理解不同继承体系下的方法调用路径,避免命名冲突带来的潜在问题。

深入理解Python中的多重继承机制

与C++类似,Python支持多重继承。虽然这一概念在理论上易于理解,但在实际应用中,当子类调用了自身未定义的属性时,系统按照何种顺序在父类中进行搜索,尤其是当多个父类包含同名属性时,便成为了一个复杂的难点。

经典类与新式类在属性查找顺序上存在显著差异。接下来,我们将分别探讨这两种类型的具体表现。

经典类的行为特征:

#! /usr/bin/python
# -*- coding:utf-8 -*-

class P1():
 def foo(self):
  print 'p1-foo'

class P2():
 def foo(self):
  print 'p2-foo'
 def bar(self):
  print 'p2-bar'

class C1(P1,P2):
 pass

class C2(P1,P2):
 def bar(self):
  print 'C2-bar'

class D(C1,C2):
 pass


if __name__ =='__main__':
 d=D()
 d.foo()
 d.bar()

代码执行结果如下:

p1-foo
p2-bar

为了更直观地理解,我们将上述代码实例转化为结构图:

观察经典类的输出结果,可以发现:

当实例d调用foo()方法时,其搜索路径为 D => C1 => P1。

当实例d调用bar()方法时,其搜索路径为 D => C1 => P1 => P2。

总结而言,经典类的属性搜索遵循“从左至右,深度优先”的原则。具体过程为:d首先检查自身是否拥有foo方法,若未找到,则向最近的父类C1查找;若C1中仍无该方法,则继续向上追溯,直至在P1中找到该方法为止,查找随即结束。

新式类的行为特征:

#! /usr/bin/python
# -*- coding:utf-8 -*-

class P1(object):
 def foo(self):
  print 'p1-foo'
  
class P2(object):
 def foo(self):
  print 'p2-foo'
 def bar(self):
  print 'p2-bar'
  
class C1(P1,P2):
 pass
 
class C2(P1,P2):
 def bar(self):
  print 'C2-bar'
  
class D(C1,C2):
 pass 
 

if __name__ =='__main__':
 print D.__mro__ #只有新式类有__mro__属性,告诉查找顺序是怎样的
 d=D()
 d.foo()
 d.bar()

代码执行结果如下:

(<class '__main__.D'>, <class '__main__.C1'>, <class '__main__.C2'>, <class '__main__.P1'>, <class '__main__.P2'>, <type 'object'>)

p1-foo
C2-bar

观察新式类的输出结果,可以发现:

当实例d调用foo()方法时,其搜索路径为 D => C1 => C2 => P1。

当实例d调用bar()方法时,其搜索路径为 D => C1 => C2。

总结而言,新式类的属性搜索采用“广度优先”的原则。

以上即为Python多重继承机制的详细解析。若有任何疑问,欢迎留言或前往社区交流讨论。感谢阅读,希望本文能对大家有所帮助,感谢各位的支持!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表