最近在学习python的多重继承。

先来了解下多重继承的概念,所谓多重继承,是指python的类可以有两个以上父类,也即有类A,类B,类C,C同时继承类A与类B,此时C中可以使用A与B中的属性与方法。那么问题来了,如果A与B中具有相同名字的方法,这个时候python怎么调用的会是哪个方法呢?

举个例子:

class A(object):
  def __init__(self):
   pass

def foo(self):

print 'A foo'

class B(object):
  def __init__(self):
   pass

def foo(self):

print 'B foo'

class C(A,B):

def __init__(self):

pass

testc = C()

testc.foo()

实际上打印出来的信息是 A foo,这就说明了调用的是A中的方法。其实在python2.2之后,多继承中基类的寻找顺序是一种广度优先算法,称之为C3的算法(后续博客我会简单介绍下C3算法)。而python2.2之前,使用的是深度优先算法来寻找基类方法。在类C的继承关系中,按照广度优先算法,则会先找到靠近C的基类A,在A中找到foo方法之后,就直接返回了,因此即使后面的基类B中也有foo方法,但是这里不会引用它。

更加清晰的多继承例子:

class A(object):
def foo(self):
print 'A foo' class B(object):
def foo(self):
print 'B foo'
def bar(self):
print 'B bar' class C1(A,B):
pass class C2(A,B):
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__.A'>, <class '__main__.B'>, <type 'object'>)

A foo (实际上搜索顺序为D=>C1=>A)
C2 bar(实际上搜索顺序为D=>C1=>C2)

可以看到,foo找到的是A类中的方法,bar找到的是C2中的方法。

其实新式类的搜索方法是采用了“广度优先”的方式去查找属性。

只有新式类有__mro__属性,该属性标记了python继承层次中父类查找的顺序,python多重继承机制中就是按照__mro__的顺序进行查找,一旦找到对应属性,则查找马上返回。

经过上面的__mro__输出可以发现,D类的继承查找路径为:D=>C1=>C2=>A=>B=>object,通过该查找路径,foo方法将会调用A的foo方法,、bar方法将调用C2的方法,通过实际实验调用,查看输出内容确实与__mro__顺序一样。

 

最新文章

  1. 给 DevOps 初学者的入门指南
  2. Yii2 如何更好的在页面注入JavaScript
  3. Magento中如何调用SQL语句
  4. centos msyql 安装与配置
  5. Mac OS X下GnuPlot的安装和配置(无法set term png等图片输出)
  6. metalink下载补丁包
  7. 转:implementing cons/car/cdr without explicit storage
  8. 操作native window的QxtWindowSystem (好像是一个IM的一部分)
  9. C# 文件操作(全部) 追加、拷贝、删除、移动文件、创建目录 修改文件名、文件夹名
  10. Qt下实现简单的UDP通信
  11. OC——关于KVC
  12. logback使用配置详解
  13. Haskell学习-高阶函数
  14. Linux rpm包安装不了
  15. JavaSE-基础语法(三)-面向对象
  16. 自学Aruba7.1-Aruba安全认证-WPA2-PSK认证(web页面配置)
  17. Delphi SetParent 嵌入其他应用程序
  18. 第一章-Javac编译器介绍
  19. 随手练——DFS小练
  20. 基于 Redis 做分布式锁

热门文章

  1. POJ2528(离散化+线段树区间更新)
  2. 【转】Pro Android学习笔记(十六):用户界面和控制(4):ImageView控件
  3. RPM包及其管理 rpm命令
  4. tomcat 自带jdk
  5. css+div制作圆角矩形的四种方法
  6. 【总结整理】JQuery基础学习---DOM篇
  7. Unusual Sequences
  8. vim加亮和自动缩进
  9. redis系列:通过通讯录案例学习hash命令
  10. Jquery常用标签