zoukankan      html  css  js  c++  java
  • python深坑集锦 -- super

    一、前言

    Python 面向对象中有继承这个概念,初学时感觉很牛逼,里面也有个super类,经常见到,最近做一些题才算是理解了。特地记录分享给后来研究的小伙伴,毕竟现在小学生都开始学了(滑稽脸)

    二、代码

    直接上干货,能把下面一个问题全答对,后面就不用看了。

    复制代码
    class A():
        def go(self):
            print ("go A go!")
        def stop(self):
            print ("stop A stop!")
        def pause(self):
            raise Exception("Not Implemented")
    class B(A):
        def go(self):
            super(B, self).go()
            print ("go B go!")
    class C(A):
        def go(self):
            super(C, self).go()
            print ("go C go!")
        def stop(self):
            super(C, self).stop()
            print ("stop C stop!")
    class D(B,C):
        def go(self):
            super(D, self).go()
            print ("go D go!")
        def stop(self):
            super(D, self).stop()
            print ("stop D stop!")
        def pause(self):
            print ("wait D wait!")
    class E(B,C):
        pass
    a = A()
    b = B()
    c = C()
    d = D()
    e = E()
    # 说明下列代码的输出结果
    a.go()
    print('--------')
    b.go()
    print('--------')
    c.go()
    print('--------')
    d.go()
    print('--------')
    e.go()
    print('--------')
    a.stop()
    print('--------')
    b.stop()
    print('--------')
    c.stop()
    print('--------')
    d.stop()
    print('--------')
    e.stop()
    print(D.mro())
    a.pause()
    b.pause()
    c.pause()
    d.pause()
    e.pause()
    复制代码

    当然,直接运行就有答案了,还是要仔细想一下,反正看到我第一次跑出的结果的时候,我都不敢相信自己的眼睛。

    step1:

    几个概念:

    继承的功能:父类的代码重用

    多态的功能:同一方法对不同类型的对象会有相应的结果

    开闭原则:对扩展开放,对修改封闭

    super类功能:新式类实现广度优先的不重复的调用父类,解决了钻石继承(多继承)的难题

    step2:

    super实现原理:通过c3算法,生成mro(method resolution order)列表,根据列表中元素顺序查询调用

    新式类调用顺序为广度优先,旧式类为深度优先

    step3:

    个人理解:

    1.调用了父类的方法,出入的是子类的实例对象

    2.新式类子类(A,B),A就在B之前

    3.super类似于嵌套的一种设计,当代码执行到super实例化后,先去找同级父类,若没有其余父类,再执行自身父类,再往下走,

      简洁点的三个原则就是:

    子类在父类前,所有类不重复调用,从左到右

    理解了以上的说法,题目就没问题了。

    也不用跑了,答案如下:

    复制代码
    a.go()# go A go!
    b.go()# go A go!# go B go!
    c.go()# go A go!# go C go!
    d.go()# go A go!# go C go!# go B go!# go D go!
    e.go()# go A go!# go C go!# go B go!
    a.stop()# stop A stop!
    b.stop()# stop A stop!
    c.stop()# stop A stop!# stop C stop!
    d.stop()# stop A stop!# stop C stop!# stop D stop!
    e.stop()# stop A stop!
    a.pause()# ... Exception: Not Implemented
    b.pause()# ... Exception: Not Implemented
    c.pause()# ... Exception: Not Implemented
    d.pause()# wait D wait!
    e.pause()# ...Exception: Not Implemented
    复制代码

    看了答案,其实还有一点,父类抛异常的情况,如果子类有不抛异常的方法,异常就不抛出了,这个设计也会很有用。

    这里就中间一个A,C,B,D的和网上常见的不太一样,促使我仔细研究了一下,其实就是个人理解第三条。

    补充:

    Python2 和Python3在这个问题上的差别

    Python2 没有默认继承object

    Python3 默认全部继承object类,都是新式类

    Python2super调用 super(开始类名,self).函数名()

    Python3  super().函数名()

    关于调用父类函数传入子类实例的栗子举一个:

    复制代码
    class A:
        def __init__(self):
            self.n = 2
    
        def add(self, m):
            print('self is {0} @A.add'.format(self))
            self.n += m
    
    
    class B(A):
        def __init__(self):
            self.n = 3
    
        def add(self, m):
            print('self is {0} @B.add'.format(self))
            super().add(m)
            print('newb')
            self.n += 3
    
    
    class C(A):
        def __init__(self):
            self.n = 4
    
        def add(self, m):
            print('self is {0} @C.add'.format(self))
            super().add(m)
            print('newc')
            self.n += 4
    
    
    class D(B, C):
        def __init__(self):
            self.n = 5
    
        def add(self, m):
            print('self is {0} @D.add'.format(self))
            super().add(m)
            self.n += 5
    
    
    d = D()
    d.add(2)
    print(d.n)
    复制代码

    夜深了,暂时会这么多就写这么多,有空研究c3原理(挖个坑先)

     来源:

    https://www.cnblogs.com/xinghuaikang/p/8481712.html

  • 相关阅读:
    node版本切换工具n的使用介绍
    nrm -- npm镜像源管理
    npm vs npx
    Dnsmasq MacOS使用介绍
    Java动态生成类以及动态添加属性
    mysql表名忽略大小写问题记录
    psotgresql之大小写
    java 按字节读写二进制文件(Base64编码解码)
    java解析复杂json:JSONObject 和 JSONArray的使用
    URL编码:怎样读取特殊字符
  • 原文地址:https://www.cnblogs.com/hansha/p/9713591.html
Copyright © 2011-2022 走看看