[英]Multiple inheritance: The derived class gets attributes from one base class only?
我試圖學習Python中的多重繼承的概念。 考慮從兩個類Base1
和Base2
派生的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個或更多沖突方法時,將調用第一個列出的類中的一個。 因為Base1
和Base2
定義了__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.