1. 程式人生 > 實用技巧 >super()的個人理解和疑問

super()的個人理解和疑問

class Base(object):
    def __init__(self):
        print ("enter Base")
        print ("leave Base")

class A(Base):
    def __init__(self):
        print ("enter A")
        Base().__init__()    # Base().__init__() 等價於        d= Base() d.__init__()。做了兩件事,一個是例項化Base,自動執行了一次init,
        print ("leave A")    # 然後再呼叫了一次例項中的init,所以Base中的列印語句會有兩次。

class B(Base):               
    def __init__(self):
        print ("enter B")
        c= Base()
        c.__init__()
        print ("leave B")

class C(A, B):   
    def __init__(self):
        print ("enter C")
        A().__init__()#這裡的語句已經特別地指明瞭例項化A,所以C()裡的引數A和B是不需要的。
        B().__init__()
        print ("leave C")

a = C()        #例項化C

>>> 
enter C      #開始執行例項C中的初始化init
enter A      #進入了A的繼承,再執行Base的init兩次,構成A Base Base Base Base A兩次
enter Base
leave Base
enter Base
leave Base
leave A
enter A
enter Base
leave Base
enter Base
leave Base
leave A
enter B  #進入B的繼承,又執行Base的init兩次,構成B base base base base B
enter Base
leave Base
enter Base
leave Base
leave B
enter B
enter Base
leave Base
enter Base
leave Base
leave B
leave C    #執行完C的init
#不難看到,如果不使用super的話,會出現例項化時的重複呼叫

使用super:

class People(object):
    def show_my_power(self):
        print(u"people")
    
class Singer(People):
    def show_my_power(self):
        super(Singer,self).show_my_power()  #當使用super時、會有一個廣度優先搜尋樹,此語句是找父類中的show_my_power,因為是廣度搜索,所以是
        print(u'singer')                    #會找到actor裡的show_my_power。
class Actor(People):
    def show_my_power(self):
        super(Actor,self).show_my_power()    #actor中的show_my_power被找到,再往上找父類,找到people,並執行people中的show_my_power
        print(u'actor')                      # 當執行完people中的show_my_power時,原路返回,列印actor,再列印singer
class Artist(Singer,Actor):
    pass

a = Artist() 
a.show_my_power()
print(a.mro())

>>>
people
actor
singer
[<class '__main__.Artist'>, <class '__main__.Singer'>, <class '__main__.Actor'>, <class '__main__.People'>, <class 'object'>]

一個存疑的實驗:

class ex(object):
    def show_my_power(self):
        print("ex")
class People(object):
    def show_my_power(self):
        print(u"people")                         
class C(People):
    def show_my_power(self):
        super(C,self).show_my_power()
        print(u'C')

class Singer(ex):
    def show_my_power(self):
        super(Singer,self).show_my_power()
        print(u'singer')
class Actor(People):
    def show_my_power(self):
        super(Actor,self).show_my_power()
        print(u'actor')
class Artist(Actor,Singer,C):
    pass

if __name__ == "__main__":                                 
   Artist().show_my_power()
   print(Artist.mro())                   #下方的mro樹顯示
>>>
ex
singer
actor
[<class '__main__.Artist'>, <class '__main__.Actor'>, <class '__main__.Singer'>, <class '__main__.ex'>, <class '__main__.C'>, <class '__main__.People'>, <class 'object'>]
object object
People ex People
Actor Singer C
Artist

繼承關係如上表,則畫繼承樹時,應該是Artist——Actor——Singer——C……等才對,為何Singer後面是ex,就不得而知了,而且執行過程直接繞過了C,不知道為什麼。