流畅的python学习笔记-第12章

软件工
• 阅读 1278

第12章-类继承

<!-- TOC -->

<!-- /TOC -->

super函数

Py 2.x 和 Py 3.x 中有一个很大的区别就是类,无论是类的定义还是类的继承。
Py 3.x 中类的继承可以直接使用 super() 关键字代替原来的 super(Class, self)。

那么 super() 到底是依据什么来继承的呢?

super()函数根据传进去的两个参数具体作用如下:

通过第一参数传进去的类名确定当前在MRO中的哪个位置。MRO(Method Resolution Order)
通过第二个参数传进去的self,确定当前的MRO列表。
class A(object):
    def name(self):
        print('name is xiaoming')
        # super(A, self).name()


class B(object):
    def name(self):
        print('name is cat')


class C(A, B):
    def name(self):
        print('name is wang')
        super(C, self).name()


if __name__ == '__main__':

    c = C()
    print(c.__class__.__mro__)
    c.name()

返回结果是:

(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
name is wang
name is xiaoming

如果把注释去掉的结果是:

(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
name is wang
name is xiaoming
name is cat



再看一个例子:

class Base(object):
    def func_1(self):
        print('this is base')


class A(Base):
    def func_1(self):
        super().func_1()
        print('this is A')


class B(Base):
    def func_1(self):
        super().func_1()
        print('this is B')


class C(A, B):
    def func_1(self):
        super().func_1()
        print('this is c')


print(C.mro())
C().func_1()

print(help(C))

返回结果:

Help on class C in module __main__:

class C(A, B)
| Method resolution order:
| C
| A
| B

“从左到到右”的意思,C继承关系最近的是A, 然后是B,最后是上层BASE。
调用方法时的入栈顺序是 C A B Base,
出栈顺序是Base B A C,

class Base(object):
    def __init__(self):
        print("Base created")


class ChildA(Base):
    def __init__(self):
        Base.__init__(self)


class ChildB(Base):
    def __init__(self):
        # super(ChildB, self).__init__()
        # 或者更简单的写法
        # super().__init__()

        # 如果不用super写法就要这样写
        print("self=", self)  # <__main__.ChildB object at 0x000001EA8CD085F8>
        mro = type(self).mro()
        print(mro)
        # [<class '__main__.ChildB'>, <class '__main__.Base'>, <class 'object'>]

        for next_class in mro[mro.index(ChildB) + 1:]:
            print(next_class)  # <class '__main__.Base'>
            if hasattr(next_class, '__init__'):
                next_class.__init__(self)
                break


print(ChildA())
print("#" * 10)
print(ChildB())

问题

看下面的代码:

class Base(object):
    def __init__(self):
        print("Base created")


class ChildA(Base):
    def __init__(self):
        print("ChildA init...")
        Base.__init__(self)


class ChildB(Base):
    def __init__(self):
        print("ChildB init..")
        # super(ChildB, self).__init__()
        # 或者更简单的写法
        super().__init__()


if __name__ == "__main__":
    print(ChildA())
    print("#" * 10)
    print(ChildB())

返回值:

ChildA init...
Base created
<__main__.ChildA object at 0x000001D089FE85F8>
##########
ChildB init..
Base created
<__main__.ChildB object at 0x000001D089FE85F8>



可以看到结果是一样的,那么 Base.__init__(self)super().__init__()
有什么区别呢?

请看这个例子:

class Base(object):
    def __init__(self):
        print("Base created")


class UserDependency(Base):
    def __init__(self):
        print("UserDependency init...")
        super().__init__()


class ChildA(Base):
    def __init__(self):
        print("ChildA init...")
        Base.__init__(self)


class ChildB(Base):
    def __init__(self):
        print("ChildB init..")
        # super(ChildB, self).__init__()
        # 或者更简单的写法
        super().__init__()


class UserA(ChildA, UserDependency):
    def __init__(self):
        print("UserA init...")
        super(UserA, self).__init__()


class UserB(ChildB, UserDependency):
    def __init__(self):
        print("UserB init...")
        super(UserB, self).__init__()


if __name__ == "__main__":
    print(UserA())
    print("#" * 10)
    print(UserB())

返回结果:

UserA init...
ChildA init...
Base created
<__main__.UserA object at 0x0000019295A38B00>
##########
UserB init...
ChildB init..
UserDependency init...
Base created
<__main__.UserB object at 0x0000019295A38B00>


这里我们看到了区别,在多重继承中,没有使用super方法的类,没有调用UserDenpendency方法

点赞
收藏
评论区
推荐文章
LosAngel LosAngel
4年前
golang包循环引用的几种解决方案
golang包循环引用的几种解决方案发表于2020年11月2日2020年11月3日(https://libuba.com/2020/11/02/golang%e5%8c%85%e5%be%aa%e7%8e%af%e5%bc%95%e7%94%a8%e7%9a%84%e5%87%a0%e7%a7%8d%e8%a7%
Stella981 Stella981
3年前
Apollo
现在,各个服务端都启动完毕,我们可以开始研究client端怎么使用apolloclient了。具体请参考https://github.com/ctripcorp/apollo/wiki/Java%E5%AE%A2%E6%88%B7%E7%AB%AF%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%971)普通jav
Stella981 Stella981
3年前
Apollo使用文档(Java)
1、apolo的github上的文档很全,大家可以去github上查看下面是java客户端使用文档https://github.com/ctripcorp/apollo/wiki/Java%E5%AE%A2%E6%88%B7%E7%AB%AF%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97(https://www.oschin
Wesley13 Wesley13
3年前
Java 入门进阶
Java入门进阶發表於20150416http://xielong.me/2015/04/16/%E6%9C%8D%E5%8A%A1%E7%AB%AF%E5%B7%A5%E7%A8%8B%E5%B8%88%E5%85%A5%E9%97%A8%E4%B8%8E%E8%BF%9B%E9%98%B6Java%E7%89%88/
Wesley13 Wesley13
3年前
Oracle 数据库勒索病毒 RushQL 处理办法
Oracle数据库勒索病毒RushQL处理办法办法来自Oracle官方:https://blogs.oracle.com/cnsupport\_news/%E5%AF%B9%E6%95%B0%E6%8D%AE%E5%BA%93%E7%9A%84%E2%80%9C%E6%AF%94%E7%89%B9%E5%B8%81%E6%94%BB%E5%8
Stella981 Stella981
3年前
SVN基本命令
SVN基本命令从远程检出代码svncohttp://路径(目录或文件的全路径)(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2F%E8%B7%AF%E5%BE%84%28%E7%9B%AE%E5%BD%95%E6%88%96%E6%96%87%E4%
Wesley13 Wesley13
3年前
Java三大特性
_Java面向对象编程三大特性:封装继承多态(https://snailclimb.gitee.io/javaguide//docs/java/Java%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86?id_11java%e9%9d%a2%e5%90%91%e5%af%b9%e8%b1%a1%e7%bc%96%e
Stella981 Stella981
3年前
Kafka 是怎么存储的?为什么速度那么快?
文章收录地址:JavaBang(https://gitee.com/iByteCoding/JavaBang/tree/master/%E7%B2%BE%E9%80%89%E6%8A%80%E6%9C%AF%E4%B8%93%E6%A0%8F/Kafka%E6%A0%B8%E5%BF%83%E5%8E%9F%E7%90%86) 专注于系统架构、
Easter79 Easter79
3年前
SVN基本命令
SVN基本命令从远程检出代码svncohttp://路径(目录或文件的全路径)(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2F%E8%B7%AF%E5%BE%84%28%E7%9B%AE%E5%BD%95%E6%88%96%E6%96%87%E4%
Wesley13 Wesley13
3年前
Eclipse插件开发调试篇
介绍本文介绍如何定制一种适合自己项目调试的方式。扩展点查看原文:http://surenpi.com/2015/08/13/eclipse%e6%8f%92%e4%bb%b6%e5%bc%80%e5%8f%91%e8%b0%83%e8%af%95%e7%af%87/(https://www.oschina.net/
Wesley13 Wesley13
3年前
IP地址的分类及各类IP的最大网络数、网络号范围和最大主机数
总结自谢希仁老师的《计算机网络》第五版每一类网络地址都由两部分组成:网络号netid主机号hostid。IP地址的分类可以参看下图:!分类的IP(http://odwpzo1jp.bkt.clouddn.com/Iternet/%E5%88%86%E7%B1%BB%E7%9A%84IP%E5%9C%B0%E5%9D%80.pn
软件工
软件工
Lv1
雁啼红叶天,人醉黄花地,芭蕉雨声秋梦里。
文章
3
粉丝
0
获赞
0