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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM