python类中super()和__init__()的区别
Python  /  管理员 发布于 7年前   167
单继承时super()和__init__()实现的功能是类似的
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
区别是使用super()继承时不用显式引用基类。
super()只能用于新式类中
把基类改为旧式类,即不继承任何基类
class Base():def __init__(self):print 'Base create'
执行时,在初始化b时就会报错:
super(childB, self).__init__()TypeError: must be type, not classobj
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):passc = childC()print c.__class__.__mro__
输出结果如下:
enter A enter B Base createleave Bleave A(<class '__main__.childC'>, <class '__main__.childA'>, <class '__main__.childB'>, <class '__main__.Base'>, <type 'object'>)
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(<class '__main__.childC'>, <class '__main__.childA'>, <class '__main__.childB'>, <class '__main__.Base'>, <type 'object'>)
从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
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[<class '__main__.childB'>, <class '__main__.childA'>, <class '__main__.Base'>, <type 'object'>]
以上所述是小编给大家介绍的python类中super()和__init__()的区别,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对站的支持!
122 在
学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..123 在
Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..原梓番博客 在
在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..博主 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..1111 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
Copyright·© 2019 侯体宗版权所有·
粤ICP备20027696号
