【问题标题】:Why do i get a type error when using super()?为什么在使用 super() 时会出现类型错误?
【发布时间】:2016-03-29 07:28:28
【问题描述】:

我刚开始学习 Python 3 中的类和继承。我想打印一个学生的名字,它是从超类 Person 继承的。不幸的是,我不断收到 TypError。

代码:

class Person(object):

    def __init__(self, name="Mike", age = 25, place_of_birth="Stockholm"):
        self.age = age
        self.name = name
        self.place_of_birth = place_of_birth


class Student(Person):

    def __init__(self, name, age, university = "University of Stockholm", gpa = 8):
        super().__init__(name, age)
        self.university = university
        self.gpa = gpa

然后我想通过调用来打印学生的姓名:

student1 = Student()
print(student1.name)

但我不断收到此错误消息:

Traceback(最近一次调用最后一次): TypeError: init() 缺少 2 个必需的位置参数:'name' 和 'age'

【问题讨论】:

  • 您没有像您声明的那样给出初始化名称和年龄。 Student() 不起作用,因为你给了它参数,而你现在没有调用它。

标签: python-3.x inheritance superclass super


【解决方案1】:

如果您希望 Student 始终默认为 Parent 类的名称和年龄,那么您不希望 Student 采用名称和年龄值。

class Student(Person):
    def __init__(self, university = "University of Stockholm", gpa = 8):
        super().__init__() # runs parent __init__ taking no values
        self.university = university
        self.gpa = gpa

>>> student1 = Student()
>>> student1.name
'Mike'
>>> student1.age
25

当您使用 super().__init__(name, age) 时,您希望将给 Student 类的名称和年龄传递给 Parent 类。但是由于您不想传递任何内容,因此会出现错误。

现在,如果您希望 Student 类能够采用父类提供的值以及默认值,您可以这样做。

class Student(Person):
    def __init__(self, name = None, age = None, university = "University of Stockholm", gpa = 8):
        if name is None and age is None:
            super().__init__()
        else:
            super().__init__(name, age)
        self.university = university
        self.gpa = gpa

这里发生的情况是,如果没有提供姓名或年龄 if name is None and age is None,那么它默认为 Person 类中的值。但是,如果同时提供了姓名和年龄,那么它将使用这些值。

>>> student1 = Student()
>>> student1.name
'Mike'
>>> student1.age
25
>>> student2 = Student('Bill', 19)
>>> student2.name
'Bill'
>>> student2.age
19

【讨论】:

  • 感谢您的清晰解释和快速响应! @DanielePantaleone
【解决方案2】:

Student__init__() 方法采用 2 位置参数:nameage。您需要在创建新实例时指定这些参数:

student1 = Student('eppe2000', 20)
print(student1.name)

如果您希望 Student 类默认为 Person 类默认参数,以防它们未指定,您可以这样做:

class Person(object):

    def __init__(self, name="Mike", age=25, place_of_birth="Stockholm"):
        self.age = age
        self.name = name
        self.place_of_birth = place_of_birth


class Student(Person):

    def __init__(self, university="University of Stockholm", gpa=8, **kwargs):
        super().__init__(**kwargs)
        self.university = university
        self.gpa = gpa


>>> s = Student()
>>> s.name
'Mike'

>>> s = Student(name="Daniele")
>>> s.name
'Daniele'

基本上,您将类Student 未知的所有关键字参数转发到其父类。并不是说如果您指定了无效的关键字(即“姓氏”),您将获得TypeError,因为StudentPerson 都没有使用关键字“姓氏”指定关键字参数。

如果您需要有关 **kwargs 的信息,请查看此帖子:https://stackoverflow.com/a/36908/3477005

【讨论】:

  • 谢谢。但我想要完成的是每个新创建的学生对象,从 Person' 类继承了 'name' 和 'age' 属性,这些属性最初设置为 'Mike' 和 25
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-26
  • 1970-01-01
  • 1970-01-01
  • 2017-02-09
  • 1970-01-01
  • 2023-01-29
  • 2019-11-03
相关资源
最近更新 更多