如果调用super()时使用适合我的直接超类的参数,那么为什么它可以尝试将这些参数传递给其他类?

2024-10-01 02:27:32 发布

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

我正在尝试根据以下继承关系构建类:

Person -> Student -> UniversityStudent -> GraduateStudent -> GradTA
     \                                                                                                   ^
      \---------------------------------> Teacher ----------------------------------/

我的代码

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

class Student(Person):
    def __init__(self,age,name,school):
        super().__init__(age,name)
        self.school = school

class UniversityStudent(Student):
    def __init__(self,age,name,school,major):
        super().__init__(age,name,school)
        self.major = major

class GraduateStudent(UniversityStudent):
    def __init__(self,age,name,school,major,advisor):
        super().__init__(age,name,school,major)
        self.advisor = advisor

class Teacher(Person):
    def __init__(self,age,name,school,subject):
        super().__init__(age,name)
        self.school = school
        self.subject = subject

class GradTA(GraduateStudent,Teacher):
    def __init__(self,name,age,school,subject,major,advisor):
        GraduateStudent.__init__(self,age,name,school,major,advisor)
        Teacher.__init__(self,age,name,school,subject)

x = GradTA(name="Peter",school="Harvard",age=25,subject="Linear Algebra",major="Mathematics",advisor="Yau")

错误消息

Traceback (most recent call last):
  File "<stdin>", line 32, in <module>
    x = GradTA(name="Peter",school="Harvard",age=25,subject="Linear Algebra",major="Mathematics",advisor="Yau")
  File "<stdin>", line 29, in __init__
    GraduateStudent.__init__(self,age,name,school,major,advisor)
  File "<stdin>", line 18, in __init__
    super().__init__(age,name,school,major)
  File "<stdin>", line 13, in __init__
    super().__init__(age,name,school)
  File "<stdin>", line 8, in __init__
    super().__init__(age,name)
TypeError: __init__() missing 2 required positional arguments: 'school' and 'subject'

错误消息表明Student.__init__()调用Person.__init__()时出现问题

如果我在Student中写入__init__()作为

class Student(Person):
    def __init__(self,age,name,school):
        self.age = age
        self.name = name
        self.school = school

class Student(Person):
    def __init__(self,age,name,school):
        Person.__init__(self,age,name)
        self.school = school

,然后一切顺利

但是我仍然想知道我最初使用super()时出了什么问题


Tags: nameselfageinitdefstudentclassfile
3条回答

我建议将super()与类构造函数一起使用

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

您的super调用无法从它继承的类运行__init__()

您可以通过向init函数添加*args, **kwargs来解决这个问题,这将允许向它和任何使用继承和超级的类传递任意位置和命名参数

class Student(Person):
    def __init__(self, school, *args, **kwargs):
        super().__init__(school=school, *args, **kwargs)
        self.school = school

只有新的参数应该添加到子类__init__方法的签名中。那些打算初始化继承的属性的将是**kwargs的一部分,并根据需要传递

class Person:
    def __init__(self, *, age, name, **kwargs):
        super().__init__(**kwargs)
        self.age = age
        self.name = name

class Student(Person):
    def __init__(self, *, school, **kwargs):
        super().__init__(**kwargs)
        self.school = school

class UniversityStudent(Student):
    def __init__(self, *, major, **kwargs):
        super().__init__(**kwargs)
        self.major = major

class GraduateStudent(UniversityStudent):
    def __init__(self, *, advisor, **kwargs):
        super().__init__(**kwargs)
        self.advisor = advisor

class Teacher(Person):
    def __init__(self, *, subject, **kwargs):
        super().__init__(**kwargs)
        self.subject = subject

class GradTA(GraduateStudent,Teacher):
    pass

x = GradTA(name="Peter",school="Harvard",age=25,subject="Linear Algebra",major="Mathematics",advisor="Yau")

注意,您不需要在GradTA中重写__init__;无论是GraduateStudent.__init__还是Teacher.__init__,它都不需要做任何事情,而且都保证运行(不管将它们列为基类的顺序如何),因为它们都正确地使用了super

相关问题 更多 >