Python:重載構造方法

對于使用過C++的人來說,構造函數(shù)與析構函數(shù)不會陌生。
構造函數(shù)在對象創(chuàng)建時被調用,析構函數(shù)在對象被銷毀時被調用。而Python中也有類似的特殊函數(shù):__new__,__init__,__del__

其中__new____init__共同構成了C++中的構造函數(shù),__del__為析構函數(shù)。


__new__在對象被創(chuàng)建時被調用,而__init__在對象被初始化時被調用。

  1. __new__ 的第一個參數(shù)是對象本身,其他的參數(shù)是用來直接傳遞給 __init__ 方法。 __new__ 方法相當不常用,但是當繼承一個不可變的類型(比如一個tuple或者string)時,它將派上用場。但這已經(jīng)超出了基礎的范圍,所以暫且不提。
  2. __init__十分常見,用以初始化對象。當父類擁有該函數(shù),而繼承的子類想要調用父類的__init__,應該使用super().__init__()而不是父類名.__init__(),以此來避免多繼承問題。

__del__在對象被銷毀時被調用,但它并不是實現(xiàn)del語法的內(nèi)置函數(shù)。它定義的是對象被銷毀時的行為,但由于Python的GC問題,所以對象銷毀的時刻無法由編寫者完全自控,所以用處也較少。

附:多繼承問題

多繼承問題是一個古老的 Feature(當一個Bug沒法修的時候就叫 Feature)。讓我們運行如下代碼

class A():
    def __init__(self):
        print("進入A…")
        print("離開A…")

class B(A):
    def __init__(self):
        print("進入B…")
        A.__init__(self)
        print("離開B…")
        
class C(A):
    def __init__(self):
        print("進入C…")
        A.__init__(self
        print("離開C…")

class D(B, C):
    def __init__(self):
        print("進入D…")
        B.__init__(self)
        C.__init__(self)
        print("離開D…")

d = D()

結果如下

進入D…
進入B…
進入A…
離開A…
離開B…
進入C…
進入A…
離開A…
離開C…
離開D…

可以看到,A的__init__被調用了兩次。而這并不是我們期待的。為此在有些語言里,禁止了多繼承。

Python的解決方法是:使用super()調用父類方法。

class A():
    def __init__(self):
        print("進入A…")
        print("離開A…")

class B(A):
    def __init__(self):
        print("進入B…")
        super().__init__()
        print("離開B…")
        
class C(A):
    def __init__(self):
        print("進入C…")
        super().__init__()
        print("離開C…")

class D(B, C):
    def __init__(self):
        print("進入D…")
        super().__init__()
        print("離開D…")

d = D()

運行結果如下

進入D…
進入B…
進入C…
進入A…
離開A…
離開C…
離開B…
離開D…

這樣A的__init__只被調用了一次

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容