簡體   English   中英

Python多重繼承不顯示類變量或第二個繼承基類的方法

[英]Python multiple inheritance is not showing class variables or method of second inherited base class

您好,社區,我正在學習OOPS概念與python作為我的課程的一部分。 我在python中遇到多重繼承問題。 以下是我的代碼:

#!/usr/bin/env python

class Base1(object):
    def __init__(self):
        self.base1var = "this is base1"


class Base2(object):
    def __init__(self):
        self.base2var = "this is base2"

class MainClass(Base1, Base2):
    def __init__(self):
        super(MainClass, self).__init__()


if __name__ == "__main__":
    a = MainClass()
    print a.base1var
    print a.base2var

並且在運行時,我收到以下錯誤

print a.base2var
AttributeError: 'MainClass' object has no attribute 'base2var'

如果我交換繼承的類的順序,則錯誤中的變量名會相應地更改。

當我想調用兩個繼承類的構造函數時,我是否使用了super()錯誤?

如何才能正確地從多個基類繼承並使用主類中的變量和方法而不會出現此錯誤?

謝謝。

你需要向Base1添加一個super調用,以便在Base1之后調用Base2的__init__ 您還可以向Base2添加super呼叫。 這沒有必要,但不會受到傷害。

class Base1(object):
    def __init__(self):
        super(Base1, self).__init__()
        self.base1var = "this is base1"

class Base2(object):
    def __init__(self):
        #super(Base2, self).__init__()
        self.base2var = "this is base2"

class MainClass(Base1, Base2):
    def __init__(self):
        super(MainClass, self).__init__()


if __name__ == "__main__":
    a = MainClass()
    print a.base1var
    print a.base2var

產量

this is base1
this is base2

順便說一下,你真的應該使用Python 3.在現代Python中, super更好。 :)

如果使用super() ,則必須始終如一地使用它以確保調用所有類的方法。 你的Base1Base2類也應該在它們的__init__()方法中調用super(...).__init__() 這將確保最終調用方法解析順序中的所有類。

當並非所有__init__()方法都有一個空參數列表時,這確實有點棘手。 在某些時候, super()會讓你調用object.__init__() ,並且永遠不會接受任何參數。 麻煩的是,您可能不知道這可能會提前發生在哪個類中。 您可以通過創建一個object子類來解決這個問題,該子類在__init__()中接受任意數量的參數,並從中派生出來。 該類不需要調用object.__init__()因為該方法實際上並沒有做任何事情(或者,如果你可能會改變偏執,你可以在不使用super()情況下調用object.__init__() super() )。

通常, super()在參數處理中需要格外小心,因為您可能不知道方法解析順序中的下一個類,因為代碼的用戶可能會使用您未預期的組合使用基類創建新類。 因此,您需要做一些工作以確保所有類中的方法簽名兼容。

有關更多信息,請參閱Raymond Hettinger的開創性Python的Super()Considered Super

基本上發生的事情是Python正在查看父類(及其父母等,請參閱本段末尾的鏈接)以獲取某些方法__init__ 它從左到右讀取類,因此它首先看到Base1 由於Base1.__init__存在,因此調用該方法。 這個答案中閱讀更詳細的解釋。

我認為調用所有適當方法的唯一方法是手動完成

class MainClass(Base1, Base2):
    def __init__(self):
        Base1.__init__(self)
        Base2.__init__(self)

然后

a = MainClass()
print(a.base1var)
print(a.base2var)

版畫

this is base1
this is base2

Base1 __init__會覆蓋Base2 __init__.py因此永遠不會創建base2var

你應該使用super ,看看Python的super()如何與多重繼承一起工作?

使用超級而不是用於那個目標並不是錯誤。解釋超級我已經改變了你的代碼

#!/usr/bin/env python

class Base1(object):
    def __init__(self):
        self.base1var = "this is base1"


class Base2(object):
    def __init__(self):
        self.base2var = "this is base2"

class MainClass(Base2, Base1):
    def __init__(self):
        super(MainClass, self).__init__()


if __name__ == "__main__":
    a = MainClass()
    print (a.base2var)

比你有

this is base2

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM