博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python类中super()和__init__()的关系【复习】
阅读量:4969 次
发布时间:2019-06-12

本文共 4629 字,大约阅读时间需要 15 分钟。

1..单继承时super()和__init__()实现的功能是类似的

使用super()继承时不用显式引用基类

class Base(object):    def __init__(self):        print 'Base create' class childA(Base):    def __init__(self):        print 'creat A ',        Base.__init__(self)  class childB(Base):    def __init__(self):        print 'creat B ',        super(childB, self).__init__() base = Base() a = childA()b = childB()#输出:Base createcreat A  Base createcreat B  Base create

2. super()只能用于新式类中。(把基类改为旧式类,即不继承任何基类)

class Base():    def __init__(self):        print 'Base create'#执行时,在初始化b时就会报错  super(childB, self).__init__()TypeError: must be type, not classobj

3。

3. super不是父类,而是继承顺序的下一个类,在多重继承时会涉及继承顺序,super()相当于返回继承顺序的下一个类,而不是父类,类似于这样的功能:

def super(class_name, self):    mro = self.__class__.mro()    return mro[mro.index(class_name) + 1]#mro()用来获得类的继承顺序。例如:class Base(object):    def __init__(self):        print 'Base create' class childA(Base):    def __init__(self):        print 'enter A '        # Base.__init__(self)        super(childA, self).__init__()        print 'leave A'  class childB(Base):    def __init__(self):        print 'enter B '        # Base.__init__(self)        super(childB, self).__init__()        print 'leave B' class childC(childA, childB):    pass c = childC()print c.__class__.__mro__#输出:enter A enter B Base createleave Bleave A(
,
,
,
,
)

supder和父类没有关联,因此执行顺序是A —> B—>—>Base

  执行过程相当于:初始化childC()时,先会去调用childA的构造方法中的 super(childA, self).__init__(), super(childA, self)返回当前类的继承顺序中childA后的一个类childB;然后再执行childB().__init()__,这样顺序执行下去。

  在多重继承里,如果把childA()中的 super(childA, self).__init__() 换成Base.__init__(self),在执行时,继承childA后就会直接跳到Base类里,而略过了childB:

enter A Base createleave A(
,
,
,
,
)

从super()方法可以看出,super()的第一个参数可以是继承链中任意一个类的名字,

  如果是本身就会依次继承下一个类;

  如果是继承链里之前的类便会无限递归下去;

  如果是继承链里之后的类便会忽略继承链汇总本身和传入类之间的类;

  比如将childA()中的super改为:super(childC, self).__init__(),程序就会无限递归下去。

  如:

File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__    super(childC, self).__init__()  File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__    super(childC, self).__init__()  File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__    super(childC, self).__init__()  File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__    super(childC, self).__init__()  File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__    super(childC, self).__init__()  File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__    super(childC, self).__init__()  File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__    super(childC, self).__init__()  File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__    super(childC, self).__init__()  File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__    super(childC, self).__init__()  File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__    super(childC, self).__init__()  File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__    super(childC, self).__init__()  File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__    super(childC, self).__init__()  File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__    super(childC, self).__init__()RuntimeError: maximum recursion depth exceeded while calling a Python object

4. super()避免重复调用

    如果childA基础Base, childB继承childA和Base,如果childB需要调用Base的__init__()方法时,就会导致__init__()被执行两次:

class Base(object):    def __init__(self):        print 'Base create' class childA(Base):    def __init__(self):        print 'enter A '        Base.__init__(self)        print 'leave A'  class childB(childA, Base):    def __init__(self):        childA.__init__(self)        Base.__init__(self) b = childB()#Base的__init__()方法被执行了两次#输出:enter A Base createleave ABase create

 

 使用super()避免重复调用,如下:

class Base(object):    def __init__(self):        print 'Base create' class childA(Base):    def __init__(self):        print 'enter A '        super(childA, self).__init__()        print 'leave A'  class childB(childA, Base):    def __init__(self):        super(childB, self).__init__() b = childB()print b.__class__.mro()#输出:enter A Base createleave A[
,
,
,
]

  

转载请注明来源:开源中国 

转载于:https://www.cnblogs.com/qingsheng/p/9593983.html

你可能感兴趣的文章
hdu 5138 CET-6 test
查看>>
页面多个Jquery版本共存的冲突问题,解决方法!
查看>>
2. 集成学习(Ensemble Learning)Bagging
查看>>
JAVA-初步认识-I/O流(字符流-缓冲区-解释)
查看>>
【python】面试常考数据结构算法
查看>>
MongoDB 3.6 开启慢查询
查看>>
Mysql事务探索及其在Django中的实践(一)
查看>>
Real World Haskell学习篇-第1章: 入门
查看>>
BZOJ 2561 最小生成树
查看>>
NOIp2018集训test-10-21 (联考六day1)
查看>>
JAVA设计模式之观察者模式
查看>>
roof
查看>>
Windows Server 2008 R2父域管理员与子域管理员相互登录访问
查看>>
【转】Linux netstat命令详解,高级面试必备
查看>>
缓冲区溢出攻击与防御
查看>>
《大道至简》读后感
查看>>
Erwin4.1.4与PowerDesign9.5
查看>>
用tablet pc开发包开发tablet pc手写输入程序
查看>>
CUDA实例练习(四):矩阵转置
查看>>
UIViewController的生命周期及iOS程序执行顺序 和ios6 处理内存警告
查看>>