Python中对象方法的定义很怪异,第一个参数一般都命名为self(相当于其它语言的this),用于传递对象本身,而在调用的时候则不必显式传递,系统会自动传递。

举一个很常见的例子:

>>> class Foo:
def bar(self, message):
print(message)

>>> Foo().bar("Hello, World.")
Hello, World.

当存在继承关系的时候,有时候需要在子类中调用父类的方法,此时最简单的方法是把对象调用转换成类调用,需要注意的是这时self参数需要显式传递,例如:

>>> class FooParent:
def bar(self, message):
print(message)

>>> class FooChild(FooParent):
def bar(self, message):
FooParent.bar(self, message)

>>> FooChild().bar("Hello, World.")
Hello, World.

这样做有一些缺点,比如说如果修改了父类名称,那么在子类中会涉及多处修改,另外,Python是允许多继承的语言,如上所示的方法在多继承时就需要重复写多次,显得累赘。为了解决这些问题,Python引入了super()机制,例子代码如下:

>>> class FooParent:
def bar(self, message):
print(message)

>>> class FooChild(FooParent):
def bar(self, message):
super(FooChild, self).bar(message)

>>> FooChild().bar("Hello, World.")
Hello, World.

表面上看 super(FooChild, self).bar(message)方法和FooParent.bar(self, message)方法的结果是一致的,实际上这两种方法的内部处理机制大大不同,当涉及多继承情况时,就会表现出明显的差异来,直接给例子:

代码一:

class A:
def __init__(self):
print("Enter A")
print("Leave A")

class B(A):
def __init__(self):
print("Enter B")
A.__init__(self)
print("Leave B")

class C(A):
def __init__(self):
print("Enter C")
A.__init__(self)
print("Leave C")

class D(A):
def __init__(self):
print("Enter D")
A.__init__(self)
print("Leave D")

class E(B, C, D):
def __init__(self):
print("Enter E")
B.__init__(self)
C.__init__(self)
D.__init__(self)
print("Leave E")

E()

结果:

Enter E
Enter B
Enter A
Leave A
Leave B
Enter C
Enter A
Leave A
Leave C
Enter D
Enter A
Leave A
Leave D
Leave E

执行顺序很好理解,唯一需要注意的是公共父类A被执行了多次。

代码二:

class A:
def __init__(self):
print("Enter A")
print("Leave A")

class B(A):
def __init__(self):
print("Enter B")
super(B, self).__init__()
print("Leave B")

class C(A):
def __init__(self):
print("Enter C")
super(C, self).__init__()
print("Leave C")

class D(A):
def __init__(self):
print("Enter D")
super(D, self).__init__()
print("Leave D")

class E(B, C, D):
def __init__(self):
print("Enter E")
super(E, self).__init__()
print("Leave E")

E()

结果:

Enter E
Enter B
Enter C
Enter D
Enter A
Leave A
Leave D
Leave C
Leave B
Leave E

在super机制里可以保证公共父类仅被执行一次,至于执行的顺序,是按照mro进行的(E.__mro__)。

疑难提醒:在python的普通中类中,继承的模式是深度优先的,也就是说对于一个对象的搜索遵循从左至右、从下到上的原则,而这从下到上的原则又优于从左至右。对本例: F E B C D A object
而对于新式类多继承,个人认为是一种按层查找的原则,会在较低层查找对象,如果没有的话再到较高层查找

原文来自:http://www.cnblogs.com/dkblog/archive/2011/02/24/1980654.html

关于Python的super用法的更多相关文章

  1. 关于Python的super用法研究

    一.问题的发现与提出 在Python类的方法(method)中,要调用父类的某个方法,在python 2.2以前,通常的写法如代码段1: 代码段1: class A:  def __init__(se ...

  2. python的super用法及含义

    注释:以下都是在python2.7版本验证的 总括:1.python解决二义性问题,经历了深度优先算法.广度优先算法.拓扑排序算法,目前python的版本都是使用拓扑算法(C3)    2.严谨sup ...

  3. Python中super的用法

    super 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO).重复调用(钻石继承)等种种问题.总之前人留下的经验就是:保持一致性 ...

  4. python中super()的一些用法

    在看python高级编程这本书的时候,在讲到super的时候,产生了一些疑惑,super在python中的用法跟其他的语言有一些不一样的地方,在网上找了一些资料,发现基本上很少有文章能把我的疑惑讲明白 ...

  5. Python中的super()用法

    Python中对象方法的定义很怪异,第一个参数一般都命名为self(相当于其它语言的this,比如:C#),用于传递对象本身,而在调用的时候则不 必显式传递,系统会自动传递. 今天我们介绍的主角是su ...

  6. Python中super的用法【转载】

    Python中super的用法[转载] 转载dxk_093812 最后发布于2019-02-17 20:12:18 阅读数 1143  收藏 展开 转载自 Python面向对象中super用法与MRO ...

  7. [python] super() 用法

    问题的发现与提出 在Python类的方法(method)中,要调用父类的某个方法,在Python 2.2以前,通常的写法如下: class A: def __init__(self): print & ...

  8. 由Python的super()函数想到的

    python-super *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !im ...

  9. Python: 你不知道的 super

    https://segmentfault.com/a/1190000007426467 Python: 你不知道的 super 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我 ...

随机推荐

  1. 3_1 wp8应用生命周期与导航事件[wp8特色开发与编程技巧]

    3_1生命周期 大家好,我是徐文康,今天我们来讨论一下应用程序的生命周期,首先打开app.xaml.cs文件我们可以看到这里有几个已经为我们写好的事件.   Launching 应用程序启动 Acti ...

  2. C# 枚举操作扩展类

    using System; using System.Linq; using System.ComponentModel; namespace Demo.Common { /// <summar ...

  3. 转:Android studio Gradle

    提高Android Studio中Gradle执行效率 分类: android studio2015-06-26 11:54 2374人阅读 评论(2) 收藏 举报 android studiogra ...

  4. Win7在CMD命令行中使用管理员权限运行命令

    使用命令: runas /user:administrator 需要执行的命令 如下:

  5. float闭合(清除浮动)和CSS HACK

    一.float 闭合(清除浮动) 将以下代码加入Global CSS 中,给需要闭合的div加上 class="clearfix" 即可,屡试不爽. <style>.c ...

  6. 通信协议之HTTP,UDP,TCP协议

    1.UDP,TCP,HTTP之间的关系 tcp/ip是个协议组,它可以分为4个层次,即网路接口层,网络层,传输层,以及应用层, 在网络层有IP协议.ICMP协议.ARP协议.RARP协议和BOOTP协 ...

  7. 【Qt】Qt之进程间通信(共享内存)【转】

    简述 上一节中,我们分享下如何利用Windows消息机制来进行不同进程间的通信.但是有很多局限性,比如:不能跨平台,而且必须两个进程同时存在才可以,要么进程A发了消息谁接收呢? 下面我们来分享另外一种 ...

  8. eclipse 安装插件不生效

    操作: 下载了一个插件,插件中只有一个jar包,解压放到plugins目录,插件没生效. 解决方法: 把jar包直接扔到dropins目录下,并且删除eclipse\configuration\org ...

  9. Ubuntu下Apache+php+mysql网站架设详解

    目录 1 基础 2 安装 2.1 安装LAMP 2.2 图形化管理软件(可选) 2.2.1 安装webmin 2.2.2 安装phpmyadmin 3 配置文件路径 3.1 常用命令 3.2 配置ap ...

  10. jquery ztree插件

    jquery json数据格式 操作tree数据 http://www.ztree.me/v3/main.php#_zTreeInfo