python类中super()和__init__()的区别
单继承时super()和__init__()实现的功能是类似的
classBase(object): def__init__(self): print'Basecreate' classchildA(Base): def__init__(self): print'creatA', Base.__init__(self) classchildB(Base): def__init__(self): print'creatB', super(childB,self).__init__() base=Base() a=childA() b=childB()
输出结果:
Basecreate creatABasecreate creatBBasecreate
区别是使用super()继承时不用显式引用基类。
super()只能用于新式类中
把基类改为旧式类,即不继承任何基类
classBase(): def__init__(self): print'Basecreate'
执行时,在初始化b时就会报错:
super(childB,self).__init__() TypeError:mustbetype,notclassobj
super不是父类,而是继承顺序的下一个类
在多重继承时会涉及继承顺序,super()相当于返回继承顺序的下一个类,而不是父类,类似于这样的功能:
defsuper(class_name,self): mro=self.__class__.mro() returnmro[mro.index(class_name)+1]
mro()用来获得类的继承顺序。
例如:
classBase(object): def__init__(self): print'Basecreate' classchildA(Base): def__init__(self): print'enterA' #Base.__init__(self) super(childA,self).__init__() print'leaveA' classchildB(Base): def__init__(self): print'enterB' #Base.__init__(self) super(childB,self).__init__() print'leaveB' classchildC(childA,childB): pass c=childC() printc.__class__.__mro__
输出结果如下:
enterA enterB Basecreate leaveB leaveA (<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:
enterA Basecreate leaveA (<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",line10,in__init__ super(childC,self).__init__() File"C:/Users/Administrator/Desktop/crawler/learn.py",line10,in__init__ super(childC,self).__init__() File"C:/Users/Administrator/Desktop/crawler/learn.py",line10,in__init__ super(childC,self).__init__() File"C:/Users/Administrator/Desktop/crawler/learn.py",line10,in__init__ super(childC,self).__init__() File"C:/Users/Administrator/Desktop/crawler/learn.py",line10,in__init__ super(childC,self).__init__() File"C:/Users/Administrator/Desktop/crawler/learn.py",line10,in__init__ super(childC,self).__init__() File"C:/Users/Administrator/Desktop/crawler/learn.py",line10,in__init__ super(childC,self).__init__() File"C:/Users/Administrator/Desktop/crawler/learn.py",line10,in__init__ super(childC,self).__init__() File"C:/Users/Administrator/Desktop/crawler/learn.py",line10,in__init__ super(childC,self).__init__() File"C:/Users/Administrator/Desktop/crawler/learn.py",line10,in__init__ super(childC,self).__init__() File"C:/Users/Administrator/Desktop/crawler/learn.py",line10,in__init__ super(childC,self).__init__() File"C:/Users/Administrator/Desktop/crawler/learn.py",line10,in__init__ super(childC,self).__init__() File"C:/Users/Administrator/Desktop/crawler/learn.py",line10,in__init__ super(childC,self).__init__() RuntimeError:maximumrecursiondepthexceededwhilecallingaPythonobject
super()可以避免重复调用
如果childA基础Base,childB继承childA和Base,如果childB需要调用Base的__init__()方法时,就会导致__init__()被执行两次:
classBase(object): def__init__(self): print'Basecreate' classchildA(Base): def__init__(self): print'enterA' Base.__init__(self) print'leaveA' classchildB(childA,Base): def__init__(self): childA.__init__(self) Base.__init__(self) b=childB()
Base的__init__()方法被执行了两次
enterA Basecreate leaveA Basecreate
使用super()是可避免重复调用
classBase(object): def__init__(self): print'Basecreate' classchildA(Base): def__init__(self): print'enterA' super(childA,self).__init__() print'leaveA' classchildB(childA,Base): def__init__(self): super(childB,self).__init__() b=childB() printb.__class__.mro() enterA Basecreate leaveA [<class'__main__.childB'>,<class'__main__.childA'>,<class'__main__.Base'>,<type'object'>]
以上所述是小编给大家介绍的python类中super()和__init__()的区别,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!