http://hi.baidu.com/thinkinginlamp/item/3095e2f52c642516ce9f32d5

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 super的更多相关文章

  1. Python ---- super()使用

    Python ---- super() 我们经常在类的继承当中使用super(), 来调用父类中的方法.例如下面: 1 2 3 4 5 6 7 8 9 10 11 12 13 class A:     ...

  2. Python super继承详解

    MRO(Method resolution order)是python用来解析方法调用顺序的,mro中记录了一个类的所有基类的类类型序列,super不是简单地调用基类的方法,而是按照MRO中的顺序来调 ...

  3. Python super使用

    一 基础使用 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能,这时,我们就需要调用父类的方法了,可通过使用 super 来实现,比如: #!/usr ...

  4. python super参数错误

    # -*- coding:utf-8 _*-"""@author:Administrator@file: yamlparser.py@time: 2018/09/07&q ...

  5. python super超类方法

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

  6. Python super() 函数的概念和例子

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

  7. python: super原理

    super() 的入门使用 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能,这时,我们就需要调用父类的方法了,可通过使用 super 来实现,比如: ...

  8. python super()函数

    super()函数是用来调用父类(超类)的一个方法 super()的语法: python 2 的用法: super(Class, self).xxx  # class是子类的名称 class A(ob ...

  9. (转)Python: super 没那么简单

    原文:https://mozillazg.com/2016/12/python-super-is-not-as-simple-as-you-thought.html python 约定¶ 单继承¶ 多 ...

随机推荐

  1. Slip.js – 在触摸屏上实现列表的滑动排序功能

    Slip.js 是一个很小的 JavaScript 库,用于实现对触摸屏的互动 Swipe 和对元素重新排序列表(Reordering).Slip.js 没有任何的依赖,你可以通过自定义 DOM 事件 ...

  2. [数据库]sql之行顺序

    这个文章主要是防止我忘了sql的执行顺序,解释的东西我都没怎么看懂.数据库渣如我- 逻辑查询处理阶段简介 FROM:对FROM子句中的前两个表执行笛卡尔积(Cartesian product)(交叉联 ...

  3. XPATH使用总结

    最近公司里需要写一些爬虫项目,所以去接触学习了xpath的内容.在w3c上给出了xpath的语法,但是我感觉不全,而且讲得也不详细,我又去网上找了一些文章,总结一下. 这几个都是比较常用的,能解决基本 ...

  4. IOS 之 PJSIP 笔记(二) iPJSUA 的简单使用

    上一篇在编译完之后,就很不负责的结束了,本篇就对 PJSIP 库中提供的一个示例 iPJSUA 的使用,做一个简单的介绍.也能解除很多人对官方文档的一个困扰,起码我是被困扰过了. 首先,要确保你的 P ...

  5. sql date()函数,时间格式

    (1).GETDATE() 函数从 SQL Server 返回当前的日期和时间. 语法 GETDATE() 实例 下面是 SELECT 语句: SELECT GETDATE() AS CurrentD ...

  6. 【循序渐进学Python】2. Python中的序列——列表和元组

    序列概览 在Python中有六种内建的序列:列表.元组.字符串.Unicode字符串.buffer对象和xrange对象.在这里暂时只讨论列表和元组.列表和元组的主要区别在于:列表可以修改,元组(不可 ...

  7. Android入门:Activity四种启动模式

    一.启动模式介绍 启动模式简单地说就是Activity启动时的策略,在AndroidManifest.xml中的标签的android:launchMode属性设置: 启动模式有4种,分别为standa ...

  8. 为什么.NET感觉上比Java差一点

    其实,我本人很喜欢.NET技术.工作经历中,大部分时间也在使用.NET开发. 这几年,由于工作的原因,开始进入Java+Linux世界. 今年,开始学习Python和Scala. 使用.NET时,有种 ...

  9. 【iOS】Quartz2D基本图形

    一.画线段 - (void)drawRect:(CGRect)rect { // Drawing code // 1.获得图形上下文 CGContextRef ctx = UIGraphicsGetC ...

  10. 深入浅出java 8 lambda表达式--零基础一分钟入门

    lambda从使用上来说,第一感觉直白的理解就是,少了很多不必要的匿名回调类的写法,比如: public static void main(String[] args) { PlatformQuery ...