簡體   English   中英

如何從2個類繼承而不必更改原始類?

[英]How to inherit from 2 classes without having to change the original classes?

每當我運行這段代碼時,我總是得到一個TypeError ,它說__init__() missing 1 required positional argument: 'hours' ,但我並沒有試圖更改ScientificSwimmer類繼承自的原始類的任何內容......如果有道理的話。

這是代碼:

class Human:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def hobby(self):
        print("Likes watching Netflix")

    def info(self):
        print(self.name , "is ",self.age," years old")


class Scientist(Human):
    def __init__(self, name, age, lab):
        super().__init__(name, age)
        self.lab = lab

    def hobby(self):
        print("Likes doing scientific experiments")

    def labName(self,lab):
        print("works at the " ,lab, "laboratory")


class Swimmer(Human):
    def __init__(self, name, age, hours):
        super().__init__(name,age)
        self.hours = hours

    def hobby(self):
        print("likes swimmming in the lake" )

    def hoursSwimming(self, hours):
        print("swims ", hours , "hours per week")


class ScientificSwimmer(Scientist, Swimmer):

    def __init__ (self, name, age, lab, hours):
       Scientist.__init__(self,name, age, lab)
       Swimmer.__init__(self, name, age, hours)


scienswim = ScientificSwimmer("\nJohn Smith", 30, "nuclear", 100)
scienswim.info()
scienswim.hobby()
scienswim.labName("nuclear")
scienswim.hoursSwimming(100)

我想要的結果是打印:

John smith is 30 years old.
likes doing scientific experiments.
works at the nuclear laboratory.
swims 100 hours per week.

您的原始類根本沒有正確設計來支持合作繼承,而這正是super的設計目的。 使用super第一條規則是:您不能假設您知道super()將引用哪個類。 這是由self運行時類型決定的,而不是您靜態繼承的類。

僅使用關鍵字參數以確保方法簽名保持兼容,並始終使用任何未知的關鍵字參數(即簽名中未明確提及的參數super().__init__調用super().__init__

class Human: 
    def __init__(self, *, name, age, **kwargs):
        super().__init__(**kwargs)
        self.name = name
        self.age = age
        
    def hobby(self):
        print("Likes watching Netflix")
        
    def info(self):
        print(self.name , "is ",self.age," years old")
        

class Scientist(Human): 
    def __init__(self, *, lab, **kwargs):
        super().__init__(**kwargs)
        self.lab = lab
        
    def hobby(self):
        print("Likes doing scientific experiments")
    
    def labName(self):
        print("works at the " , self.lab, "laboratory")
  

class Swimmer(Human):
    def __init__(self, *, hours, **kwargs):
        super().__init__(**kwargs)
        self.hours = hours
    
    def hobby(self):
        print("likes swimmming in the lake" )
    
    def hoursSwimming(self):
        print("swims ", self.hours , "hours per week")
     

class ScientificSwimmer(Scientist, Swimmer):
    pass


scienswim = ScientificSwimmer(name="John Smith", age=30, lab="nuclear", hours=100)
scienswim.info()
scienswim.hobby()
scienswim.labName()
scienswim.hoursSwimming()

ScientificSwimmer的方法解析順序是[ScientificSwimmer, Scientist, Swimmer, Human, object] 這導致以下結果:

  1. ScientificSwimmer不需要定義,因為其他__init__方法會處理一切。
  2. Scientist.__init__提取lab關鍵字參數並將其余部分傳遞給下一個類。
  3. Swimmer.__init__提取hours關鍵字參數並將其余部分傳遞給下一個類。
  4. Human.__init__提取nameage關鍵字參數並將其余部分傳遞給下一個類。
  5. object.__init__接收關鍵字參數,所有定義的參數都已被下游類正確提取。

暫無
暫無

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

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