超类中的调用方法没有给出我期望的输出?

时间:2018-03-18 21:53:36

标签: python python-3.x oop superclass

我正在学习Python中的继承,我正在尝试使用超类和super()函数。这是我的代码:

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

    def describe(self):
        return f"{self.name}, {self.age}, {self.weight}"


class Engineer(Person):
    def __init__(self, name, age, weight):
        super().__init__("Bla bla", 10, 100)
        self.name = name
        self.age = age
        self.weight = weight
        self.occupation = "Engineer"

    def describe(self):
        return super().describe()

my_engineer = Engineer("Larry", 17, 120)
print(my_engineer.describe())

我有一个Java背景,显然super()在Python中的工作方式与在Java中的工作方式不同。在Java中,与此等效的代码输出为Bla bla, 17, 120,但此代码输出Larry, 17, 120。为什么此代码打印出Larry, 17, 120而不是我预期的?根据我的理解,我正在实例化课程Engineer并将"Larry"17120传递给__init__,但随后我传入{{1} }},"Bla bla"10到超类的100,因此应使用这些值初始化超类。然后当我调用__init__时,它应该调用超类中的my_engineer.describe()并使用超类传入的值。但显然,这不是正在发生的事情。谁能解释一下发生了什么?

2 个答案:

答案 0 :(得分:4)

super工作正常;但是,在super调用之后,您将使用传递给子构造函数的值覆盖每个属性。相反,只需调用super并且不要使用相同的属性初始化子类:

class Engineer(Person):
   def __init__(self, *args):
      super().__init__("Bla bla", 10, 100)
   def describe(self):
      return super().describe()

my_engineer = Engineer("Larry", 17, 120)
print(my_engineer.describe())

输出:

Bla bla, 10, 100

答案 1 :(得分:3)

您正在查看被覆盖的属性。这些代码行中发生了什么:

super().__init__("Bla bla", 10, 100)
self.name = name
self.age = age
self.weight = weight
self.occupation = "Engineer"
  • super().__init__("Bla bla", 10, 100)使用这些值调用Person' __init__,即self = Person("Bla bla", 10, 100)。如果你在这里停下来,你已经实例化了Person的子类,并没有真正改变任何东西。 (相同的属性,相同的方法。)
  • 然后,当您指定接下来的四个属性时,将覆盖您在上一行中执行的操作。它们直接设置为类实例的属性。

基本上,这看起来像Python:

my_engineer = Person("Bla bla", 10, 100)
my_engineer.name = "Larry"
my_engineer.age = 17
my_engineer.weight = 120
my_engineer.occupation = "Engineer"

正如@ Ajax1234所提到的,看起来你想完全摆脱这四行。