python3 super().__init__() 和 __init__() 的区别

1、单继承

super().__int__()和 Base.__init__(self)是一样的, super()避免了基类的显式调用。

class Base(object):
    def __init__(self):
        print('Create Base')

class ChildClassA(Base):
    def __init__(self):
        print('Create ChildClassA')
        super().__init__()

ChildClassA()
#输出
#Create ChildClassA
#Create Base

2、多继承

注意:多继承时,会设计继承顺序,supper()相当于返回继承顺序的下一个类,而不是父类。

def GetSupperOrder(class_name,self):
    mro = self.__class__.mro()
    # #mro()用来获得类的继承顺序。
    return mro[mro.index(class_name) + 1]

class Base(object):
    def __init__(self):
        print('Create Base')

class ChildClassA(Base):
    def __init__(self):
        print('Enter ChildClassA')
        super().__init__()
        print('Leave ChildClassA')

class ChildClassB(Base):
    def __init__(self):
        print('Enter ChildClassB')
        super().__init__()
        print('Leave ChildClassB')

class ChildClassC(ChildClassA,ChildClassB):
    pass

c = ChildClassC()
print(c.__class__.__mro__)
# 输出:
#Enter ChildClassA
#Enter ChildClassB
#Create Base
#Leave ChildClassB
#Leave ChildClassA
#(<class '__main__.ChildClassC'>, <class '__main__.ChildClassA'>, <class '__main__.ChildClassB'>, <class '__main__.Base'>, <class 'object'>)

从以上结果,可以看出:
super()和父类没有关系,继承执行的顺序是 ChildClassA → ChildClassB → Base → Object

执行过程:
首先初始化ChlidClassC() ,初始化时先调用ChildClassA的构造方法__Init__(),
进而调用super().__init__()方法,此方法返回当前类的继承顺序中ChildClassA后的一个类ChildClassB,然后在执行ChildClassB的构造方法,
最后执行Base的构造方法,然后依次返回,并执行完成。

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

Enter ChildClassA
Create Base
Leave ChildClassA
(<class '__main__.ChildClassC'>, <class '__main__.ChildClassA'>, <class '__main__.ChildClassB'>, <class '__main__.Base'>, <class 'object'>)

 

从super()方法可以看出,super()的第一个参数可以是继承链中任意一个类的名字,
  如果是本身就会依次继承下一个类;

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

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

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

Enter ChildClassA
Enter ChildClassA
Enter ChildClassA
...
Enter ChildClassA
Enter ChildClassA
Enter ChildClassA
Enter ChildClassA
  File "D:/Python20190819/WebApp/venv/Include/testunit.py", line 53, in <module>
    c = ChildClassC()
  File "D:/Python20190819/WebApp/venv/Include/testunit.py", line 41, in __init__
    super(ChildClassC, self).__init__()
  File "D:/Python20190819/WebApp/venv/Include/testunit.py", line 41, in __init__
    super(ChildClassC, self).__init__()
  File "D:/Python20190819/WebApp/venv/Include/testunit.py", line 41, in __init__
    super(ChildClassC, self).__init__()
  [Previous line repeated 992 more times]
  File "D:/Python20190819/WebApp/venv/Include/testunit.py", line 40, in __init__
    print('Enter ChildClassA')
RecursionError: maximum recursion depth exceeded while calling a Python object

3、super()避免重复调用

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

"""
单继承 super().__int__()和 Base.__init__(self)是一样的, super()避免了基类的显式调用。

class Base(object):
    def __init__(self):
        print('Create Base')

class ChildClassA(Base):
    def __init__(self):
        print('Create ChildClassA')
        super().__init__()

class ChildClassB(Base):
    def __init__(self):
        print('Create ChildClassB')
        super().__init__()


ChildClassA()
#输出
#Create ChildClassA
#Create Base
"""

"""
多继承:
注意:多继承时,会设计继承顺序,supper()相当于返回继承顺序的下一个类,而不是父类。
"""

class Base(object):
    def __init__(self):
        print('Create Base')

class ChildClassA(Base):
    def __init__(self):
        print('Enter ChildClassA')
        Base.__init__(self)
        print('Leave ChildClassA')

class ChildClassB(ChildClassA,Base):
    def __init__(self):
        print('Enter ChildClassB')
        ChildClassA.__init__(self)
        Base.__init__(self)
        print('Leave ChildClassB')

b = ChildClassB()

# 输出:
Enter ChildClassB
Enter ChildClassA
Create Base
Leave ChildClassA
Create Base
Leave ChildClassB

supper() 避免重复

"""
单继承 super().__int__()和 Base.__init__(self)是一样的, super()避免了基类的显式调用。

class Base(object):
    def __init__(self):
        print('Create Base')

class ChildClassA(Base):
    def __init__(self):
        print('Create ChildClassA')
        super().__init__()

class ChildClassB(Base):
    def __init__(self):
        print('Create ChildClassB')
        super().__init__()


ChildClassA()
#输出
#Create ChildClassA
#Create Base
"""

"""
多继承:
注意:多继承时,会设计继承顺序,supper()相当于返回继承顺序的下一个类,而不是父类。
"""

class Base(object):
    def __init__(self):
        print('Create Base')

class ChildClassA(Base):
    def __init__(self):
        print('Enter ChildClassA')
        super( ).__init__()
        print('Leave ChildClassA')

class ChildClassB(ChildClassA,Base):
    def __init__(self):
        print('Enter ChildClassB')
        super().__init__()
        print('Leave ChildClassB')

b = ChildClassB()

# 输出:
Enter ChildClassB
Enter ChildClassA
Create Base
Leave ChildClassA
Leave ChildClassB

 参考自:开源中国 http://my.oschina.net/jhao104/blog/682322

posted @ 2019-08-29 10:28  猪快跑  阅读(4054)  评论(0编辑  收藏  举报