我是靠谱客的博主 心灵美小鸽子,这篇文章主要介绍python类中super()和__init__()的区别,现在分享给大家,希望可以做个参考。

最近有同学问我关于Python类中的super()和__init__()共同点和不同点的问题, 我今天把它们两个的异同点总结了一下,希望可以帮助遇到同样困惑的同学。

 

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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()
=  childA()
=  childB()

输出结果:

1
2
3
Base create
creat A  Base create
creat B  Base create

区别是使用super()继承时不用显式引用基类。

 

super()只能用于新式类中

 

把基类改为旧式类,即不继承任何基类

1
2
3
class  Base():
     def  __init__( self ):
         print  'Base create'

执行时,在初始化b时就会报错:

1
2
super(childB, self).__init__()
TypeError: must be  type , not classobj

 

super不是父类,而是继承顺序的下一个类

 

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

1
2
3
def  super (class_name,  self ):
     mro  =  self .__class__.mro()
     return  mro[mro.index(class_name)  +  1 ]

mro()用来获得类的继承顺序。 例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
=  childC()
print  c.__class__.__mro__

输出结果如下:

1
2
3
4
5
6
enter A 
enter B 
Base create
leave B
leave 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:

1
2
3
4
enter A 
Base create
leave A
(<class  '__main__.childC' >, <class  '__main__.childA' >, <class  '__main__.childB' >, <class  '__main__.Base' >, < type  'object' >)

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

 

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

 

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

 

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

 

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
   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__()被执行两次:

1
2
3
4
5
6
7
8
9
10
11
12
13
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 )
=  childB()

Base的__init__()方法被执行了两次

1
2
3
4
enter A 
Base create
leave A
Base create

 

使用super()是可避免重复调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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__()
=  childB()
print  b.__class__.mro()
enter A 
Base create
leave A
[< class  '__main__.childB' >, < class  '__main__.childA' >, < class  '__main__.Base' >, < type  'object' >]

 

转载于:https://www.cnblogs.com/paranoia/p/6165300.html

最后

以上就是心灵美小鸽子最近收集整理的关于python类中super()和__init__()的区别的全部内容,更多相关python类中super()和__init__()内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(51)

评论列表共有 0 条评论

立即
投稿
返回
顶部