簡體   English   中英

多重繼承:派生類僅從一個基類獲取屬性?

[英]Multiple inheritance: The derived class gets attributes from one base class only?

我試圖學習Python中的多重繼承的概念。 考慮從兩個類Base1Base2派生的Derv類。 Derv僅從第一個基類繼承成員:

class Base1:
    def __init__(self):
        self.x=10

class Base2:
    def __init__(self):
        self.y=10

class Derv (Base1, Base2):
    pass

d = Derv()
print (d.__dict__)

結果為{ 'x' : 10 } ,顛倒繼承順序僅得到{ 'y' : 10 }

派生類不應該從兩個基類繼承屬性嗎?

我不完全理解為什么會這樣,但是我可以告訴您如何解決:

由於某種原因,Python僅調用其父級之一的__init__方法。 但是,這可以解決您的問題:

class Base1:
     def __init__(self):
         super().__init__()
         print('b1')
         self.x=10

 class Base2:
     def __init__(self):
         super().__init__() # This line isn't needed. Still not sure why
         print('b2')
         self.y=10

 class Derv (Base1, Base2):

     def __init__(self):
         super().__init__()

 d = Derv()
 print (d.__dict__)


'b2'
'b1'
{'y': 10, 'x': 10}

更新,添加打印語句實際上可以說明情況。 例如,

class Base1:
     def __init__(self):
         print('Before Base1 call to super()')
         super().__init__()
         print('b1')
         self.x=10

 class Base2:
     def __init__(self):
         print('Before Base2 call to super()')
         super().__init__() # No remaining super classes to call
         print('b2')
         self.y=10

 class Derv (Base1, Base2):

     def __init__(self):
         super().__init__()

 d = Derv()
 print (d.__dict__)

'Before Base1 call to super()' # Just before the call to super
'Before Base2 call to super()' # Just before call to super (but there are no more super classes)
'b2' # Calls the remaining super's __init__
'b1' # Finishes Base1 __init__
{'y': 10, 'x': 10}

當一個類繼承自多個超類,並且有2個或更多沖突方法時,將調用第一個列出的類中的一個。 因為Base1Base2定義了__init__ ,所以將調用第一個列出的類中__init__的版本,因此不會同時定義這兩個屬性。

這在Python文檔中有更好的解釋。

在大多數情況下,在最簡單的情況下,您可以將對從父類繼承的屬性的搜索視為深度優先,從左到右, 而不是在層次結構重疊的同一類中進行兩次搜索 因此,如果在DerivedClassName中找不到屬性,則在Base1中搜索該屬性,然后(遞歸)在Base1的基類中,如果在該屬性中找不到該屬性,則在Base2中搜索該屬性,依此類推。

然后,因為__init__首先在您的左課中找到,所以它不會尋找其他人。 正如其他用戶解釋的那樣,應該使用super()來讓Python知道如何尋找其他__init__方法。

您可以使用以下類屬性創建對象:

class Base1:
    x=10

class Base2:
    y=10

然后,您的Derv類確實將繼承這兩個屬性。

class Derv (Base1, Base2):
    pass

d = Derv()
print(d.x, d.y)  # prints: 10, 10

創建對象的實例(即d = Derv() )時,將調用__init__方法。 一個對象只能具有給定方法的一個版本,因此您的Derv類僅繼承第一個。

暫無
暫無

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

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