如何从2个类继承而不必更改原始类?

2024-09-30 18:19:40 发布

您现在位置:Python中文网/ 问答频道 /正文

每当我运行这段代码时,我总是得到一个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.

Tags: thenameselfageinitdeflabclass
1条回答
网友
1楼 · 发布于 2024-09-30 18:19:40

您的原始类根本没有正确地设计为支持协作继承,这就是super的设计目的。使用super的第一条规则是:不能假设您知道super()将引用哪个类。这是由self运行时类型决定的,而不是静态继承自的类

只使用关键字参数以确保方法签名保持兼容,并始终使用任何未知关键字参数(即签名中未明确提及的参数)调用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不需要定义,因为其他{}方法将处理所有事情
  2. Scientist.__init__提取lab关键字参数,并将其余参数传递给下一个类
  3. Swimmer.__init__提取hours关键字参数,并将其余参数传递给下一个类
  4. Human.__init__提取nameage关键字参数,并将其余参数传递给下一个类
  5. object.__init__未接收任何关键字参数,下游类已正确提取所有定义的参数

相关问题 更多 >