Python支持多继承,与C++一样都会出现一种问题:子类继承的多个父类又继承了同一个父类,这时就有可能会出现父类构造方法被调用多次的情况。关于这个问题,我找了一些资料,虽然没有亲自全部验证,这里我总结一下自己对这个问题的看法。

  Python和C++的关于这个问题的解决方案不太一样,当然Python还要看它的版本。

  C++用的方案是引入了虚继承的语法避免同一个类被构造了多次。

  Python用的方法是MRO(method resolution order,方法解析顺序) 。在在Python2.3之前,MRO的实现是基于DFS的,而在Python2.3以后MRO的实现是基于C3算法。找到的资料解释了一下更换算法的原因:

  为什么采用C3算法
  C3算法最早被提出是用于Lisp的,应用在Python中是为了解决原来基于深度优先搜索算法不满足本地优先级,和单调性的问题。
  本地优先级:指声明时父类的顺序,比如C(A,B),如果访问C类对象属性时,应该根据声明顺序,优先查找A类,然后再查找B类。
  单调性:如果在C的解析顺序中,A排在B的前面,那么在C的所有子类里,也必须满足这个顺序。
------------------------------新式类和旧式类中查找属性的顺序不同-------------------------------------
  在新式类中,查找一个要调用的函数或者属性的时候,是广度优先搜搜的。
  在旧式类当中,是深度优先搜索的。如下图所示:
  来一个例子:
  

 # -*- coding:utf-8 -*-

 class D(object):
def foo(self):
print "class D" class B(D):
pass class C(D):
def foo(self):
print "class C" class A(B, C):
pass f = A()
f.foo()
  例子中定义D类的时候,D是新式类,所以D的所有子类都是新式类。
  A的实例对象f在调用foo函数的时候,根据广度优先搜索原则,调用的是C类里面的foo函数。
  上面的代码输出class C
  如果定义D类的时候直接class D,而不是class D(object),那么上述代码就该输出class D了。

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

  如果我用的是super来解决多继承的初始化问题的话,那么到底是怎么初始化的呢?

  这是我一开始想到的一个问题:

  

 class A(object):
def __init__(self,a):
print a class B(object):
def __init__(self,a,b):
print a+b class C(A,B):
def __init__(self):
super(C,self).__init__(?) obj = C()

  第十一行的那个'?'的位置到底是填是什么进去才对呢?

  我一开始认为因为是多继承多以需要初始化父类的时候A,B都需要初始化,那么问题来了,super(C,self).__init__(?)怎么写?

  我试了一下:

  ① ? = 1      -->  输出1

  ② ? = 1,2       --> TypeError: __init__() takes exactly 2 arguments (3 given)

  定义C的时候改成class(B,A)

  ③ ? = 1      --> TypeError: __init__() takes exactly 3 arguments (2 given)

  ④ ? =1,2        --> 输出3

  再来看另一段代码:

 class A(object):
def func(self):
print 1 class B(object):
def __init__(self):
print 2 class C(A,B):
def __init__(self):
super(C,self).__init__() obj = C()
#The output is 3

  说明什么问题?在调用super(classname,self).__init__()的时候应该调用在继承的父类列表里面有实现__init__()这个方法而且最靠左边的那个父类的构造方法,而且这个__init__(?)的'?'一定要与父类列表的里面第一个有构造方法的父类的构造方法签名一样才可以。

  所以如果需要对所有父类都进行一遍初始化,还是使用类通过类名调用未绑定的初始化方法好(我说这一句话是因为我还不是很了解super)。

  说一下super的使用:

    super( classname,对象(一般情况是self) ) 返回的是一个super对象,你可以把它当作父类列表里面有实现__init__()这个方法而且最靠左边的那个父类的一个对象就可以了。

  参考文章地址:

    http://blog.csdn.net/imzoer/article/details/8737642

    http://blog.csdn.net/zyflying/article/details/8636006

Python - 对多继承以及super的一些了解的更多相关文章

  1. python's twenty day for me 继承 和 super()方法

    super(): 在单继承中就是单纯的寻找父类. 在多继承中就是根据子节点所在图 的mro顺序,找寻下一个类. 遇到多继承和super(): 对象.方法 1,找到这个对象对应的类. 2,将这个类的所有 ...

  2. 关于Python中的类普通继承与super函数继承

    关于Python中的类普通继承与super函数继承 1.super只能用于新式类 2.多重继承super可以保公共父类仅被执行一次 一.首先看下普通继承的写法 二.再看看super继承的写法 参考链接 ...

  3. Python大神必须掌握的技能:多继承、super和MRO算法

    本文主要以Python3.x为例讲解Python多继承.super以及MRO算法. 1. Python中的继承 任何面向对象编程语言都会支持继承,Python也不例外.但Python语言却是少数几个支 ...

  4. python继承之super

    super() 函数是用于调用父类(超类)的一个方法. super 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO).重复调用( ...

  5. python语言中多继承中super调用所有父类的方法以及要用到的MRO顺序

    在python多继承中,利用super().父类方法,可以调用所有父类,从而在重写的状态下,再次对所有父类的调用! 例: print("******多继承使用super().__init__ ...

  6. python面向对象单继承,多继承和super()调用

    python 目录 python 1.继承 1.单继承 2.多继承 3.子类重写父类的同名属性和方法 核心点: 4.多层继承 5.super()的使用 1.继承 1.单继承 说明: 虽然子类没有定义_ ...

  7. python小兵 面向对象继承super和c3算法

    python多继承 在前面的学习过程中. 我们已经知道了Python中类与类之间可以有继承关系. 当出现了x是一种y的的时候. 就可以使⽤继承关系. 即"is-a" 关系. 在继承 ...

  8. [python] 在 python2和3中关于类继承的 super方法简要说明

    下面举一个例子,同样的代码使用 python2 和 python3 写的,大家注意两段程序中红色加粗的部分: python2的类继承使用super方法: #-*- coding:utf-8 -*- ' ...

  9. Python 中的继承、多态和封装

    涉及问题: Python 中如何实现多继承,会有什么问题? Python 中的多态与静态方法有什么区别? 答案要点如下: Python 中的继承,就是在定义类时,在括号中声明父类,简单示例如下: cl ...

随机推荐

  1. [Swift]二分法的两种方式

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  2. jenkins手把手教你从入门到放弃02-jenkins在Windows系统安装与配置(详解)

    简介 上一篇对jenkins有了大致了解之后,那么我们就开始来安装一下jenkins. Jenkins安装 一.安装Java环境 1.你需要做的第一件事情就是在你的机器上安装Java环境.Jenkin ...

  3. php做APP接口开发,接口的安全性

    1.当用户登录APP时,使用https协议调用后台相关接口,服务器端根据用户名和密码时生成一个access_key,并将access_key保存在session(或者保存在redis)中,将生成的ac ...

  4. [Qt Creator 快速入门] 第0篇 开始学习Qt 与Qt Creator

    Qt官方信息 Qt官网:http://qt.digia.com/ Qt开源官网:http://qt-project.org/ Qt最新版本下载:http://qt-project.org/downlo ...

  5. [CREC2007/CQOI2014]robotic sort

    Description 一个实验室里有n个长短不一的试管.你的任务是编写一段程序,用机器臂把它们按照高度从小到大的顺序排列. 对于高度相同的试管,排序前后的相对位置应保持不变.排序方法如图所示. 排序 ...

  6. 利用反射给JAVABEAN实例赋值

    为简化和统一,需要给javabean实例统一赋值,实现代码如下(已测试) import java.util.ArrayList; import java.util.Date; import java. ...

  7. 人人都能读懂的css3 3d小demo

    css3 3d案例总结 最近入坑 Web 动画,所以把自己的学习过程记录一下分享给大家.就把最近做的比较好的给大家分享下 1.旋转拼图 首先看下效果 代码主要由HTML和CSS3组成,应该说还是比较简 ...

  8. 动态代理在WEB与JDBC开发中的应用

    WEB案例 目前有一个2005年开始,基于Struts1的Web项目A,其验证部分依赖于主站的SSO(单点登录).在请求站点A的时候,用户会被强制带去做SSO验证,通过身份验证后后,主站会自动地把请求 ...

  9. python计算auc指标

    1.安装scikit-learn 1.1Scikit-learn 依赖 Python (>= 2.7 or >= 3.3), NumPy (>= 1.8.2), SciPy (> ...

  10. 浮动布局demo

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...