python类中super()和__init__()的区别 淡淡的烟草味﹌ 2024-03-31 10:56 15阅读 0赞 最近有同学问我关于Python类中的super()和\_\_init\_\_()共同点和不同点的问题, 我今天把它们两个的异同点总结了一下,希望可以帮助遇到同样困惑的同学。 **单继承时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 create creat A Base create creat 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): pass c = childC() print c.**class**.**mro** 输出结果如下: enter A enter B Base create leave B leave 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 create leave A (, , , , ) 从super()方法可以看出,super()的第一个参数可以是继承链中任意一个类的名字, 如果是本身就会依次继承下一个类; 如果是继承链里之前的类便会无限递归下去; 如果是继承链里之后的类便会忽略继承链汇总本身和传入类之间的类; 比如将childA()中的super改为:super(childC, self).**init**(),程序就会无限递归下去。 如: File “test.py”, line 12, in **init** super(childC, self).**init**() File “test.py”, line 12, in **init** super(childC, self).**init**() File “test.py”, line 12, in **init** super(childC, self).**init**() File “test.py”, line 12, in **init** super(childC, self).**init**() File “test.py”, line 12, in **init** super(childC, self).**init**() File “test.py”, line 12, in **init** super(childC, self).**init**() File “test.py”, line 12, in **init** super(childC, self).**init**() File “test.py”, line 12, in **init** super(childC, self).**init**() File “test.py”, line 12, 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 create leave A Base 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 create leave A \[, , , \] 转自:[https://www.weidianyuedu.com][https_www.weidianyuedu.com] [https_www.weidianyuedu.com]: https://www.weidianyuedu.com
还没有评论,来说两句吧...