我一直在練習多重繼承,這個例子聽起來很奇怪,但這就是我的想法......
這是一個名為 Pet 的主要課程,它有兩個孩子 Cat 和 Fish,我想在另一個課程中混合 cat 的技能和 fish 的技能,但似乎行不通,有什么想法嗎?
class Pet:
def __init__(self, name, age):
self.name = name
self.age = age
class Cat(Pet):
def __init__(self, name, age,climb):
super().__init__(name, age)
self.mtsClimbed = climb
class Fish(Pet):
def __init__(self, name, age, breathing, living):
super().__init__(name, age)
self.breathing = breathing
self.place_living = living
class fishCat(Cat, Fish):
def __init__(self, name, age, climb, breathing, living ):
Cat.__init__(self, name, age, climb)
Fish.__init__(self, name, age, breathing, living)
fishy = fishCat('Garfield', 2, '20 mts' , 'Water', 'Sea')
我得到的錯誤
line 15, in __init__super().__init__(name, age)
TypeError: Fish.__init__() missing 2 required positional arguments: 'breathing' and 'living'
uj5u.com熱心網友回復:
super()不呼叫第一個父類的方法。它呼叫MRO中的下一個方法,或方法決議順序(鏈接適用于 Python 2.3,但今天仍在使用相同的演算法)。
class Pet:
pass
class Cat(Pet):
pass
class Fish(Pet):
pass
class fishCat(Cat, Fish):
pass
有了這個繼承層次結構,MROfishCat就是[fishCat, Cat, Fish, Pet, object]. mro()您可以使用類上的方法在 Python 中驗證這一點。
>>> fishCat.mro()
[<class '__main__.fishCat'>, <class '__main__.Cat'>, <class '__main__.Fish'>, <class '__main__.Pet'>, <class 'object'>]
這意味著,如果你有一個fishCat物件并Cat.__init__呼叫super().__init__,那么它實際上會呼叫Fish.__init__,盡管它Cat不是 的子類Fish。
通常,如果您希望在 Python 中處理像這樣的復雜菱形繼承情況,您應該將所有引數作為關鍵字引數,并讓您的建構式接受(并轉發)它無法識別的任何關鍵字引數。
class Pet:
def __init__(self, name, age, **kwargs):
self.name = name
self.age = age
class Cat(Pet):
def __init__(self, climb, **kwargs):
super().__init__(**kwargs)
self.mtsClimbed = climb
class Fish(Pet):
def __init__(self, breathing, living, **kwargs):
super().__init__(**kwargs)
self.breathing = breathing
self.place_living = living
class fishCat(Cat, Fish):
def __init__(self, **kwargs):
super().__init__(**kwargs)
# Any fishCat-specific initialization goes here ...
這確實迫使您僅使用關鍵字引數呼叫建構式,因此fishCat('Garfield', 2, '20 mts', 'Water', 'Sea')必須替換為fishCat(name='Garfield', age=2, climb='20 mts', breathing='Water', living='Sea'). 但是考慮到您擁有的復雜繼承層次結構,這種詳細程度可能是一種改進。
旁注:值得質疑的是,鉆石繼承是否真的是這里的最佳解決方案。如果在您的域模型中某事物可能是一只貓和一條魚,那么您可能會考慮使用其他技術而不是子類化。例如,“寵物型別”可以是您的類的一個屬性,并且Pet(在此示例中不再有子類)的一個實體將有一個串列,該串列self.pet_attributes指示它能夠做的所有事情。從您在這里展示的小樣本來看,在我看來,子類化可能不是這里最理想的解決方案。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/530886.html
下一篇:如何使用類的多個實體更新單個陣列
