Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在超类中调用方法没有给出我期望的输出?_Python_Python 3.x_Oop_Superclass - Fatal编程技术网

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

Python 在超类中调用方法没有给出我期望的输出?,python,python-3.x,oop,superclass,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.w

我正在学习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,17120
,但此代码正在输出
Larry,17120
。为什么这段代码打印出来的不是我期望的,而是17岁、120岁的拉里?据我所知,我正在实例化类
Engineer
,并将
“Larry”
17
120
传递到
\uuuu init\uuuuuu
,然后将
“Bla Bla”
10
100
传递到超类的
\uuuuu init,因此,应该使用这些值初始化超类。然后,当我调用
我的工程师.descripe()
时,它应该在超类中调用
descripe()
,并使用超类传入的值。但显然,这并不是正在发生的事情。有人能解释发生了什么吗?

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

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

您将看到属性被覆盖。这些代码行中发生了什么:

super().__init__("Bla bla", 10, 100)
self.name = name
self.age = age
self.weight = weight
self.occupation = "Engineer"
  • super()。如果您停在这里,您将实例化
    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所提到的,您似乎只想完全去掉这四行。

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

super().__init__("Bla bla", 10, 100)
self.name = name
self.age = age
self.weight = weight
self.occupation = "Engineer"
  • super()。如果您停在这里,您将实例化
    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所提到的,似乎您只想完全去掉这四行。

您立即显式地替换父级
\uuuuu init\uuuu
设置的属性值;为什么会如此令人惊讶?“我有Java背景,显然super()在Python中的工作方式与在Java中的不同。”你是对的
super()
在Python中的工作方式与在Java中不同。作为建议,最好不要试图将用一种语言学习的概念投射到你正在学习的另一种语言上。虽然语言确实有某些广泛的共同点(在本例中是继承),但这些概念的实现方式通常非常不同。学习一门新语言时,最好将其视为一门独立的、独特的语言,而不要从所学的其他语言中导入其他思想。您可以立即显式替换父级
\uuuuuu init\uuuu
设置的属性值;为什么会如此令人惊讶?“我有Java背景,显然super()在Python中的工作方式与在Java中的不同。”你是对的
super()
在Python中的工作方式与在Java中不同。作为建议,最好不要试图将用一种语言学习的概念投射到你正在学习的另一种语言上。虽然语言确实有某些广泛的共同点(在本例中是继承),但这些概念的实现方式通常非常不同。当学习一门新语言时,最好将它作为一门独立的、独特的语言来对待,而不要从其他学习过的语言中引入其他思想。因此,我从中得到的是,在Python中,最好调用
super()当您设置子类的属性时,在子类的
\uuuuuu init\uuuu
的末尾而不是开头,而不是在子类的
\uuuuuuu init\uuuu
的末尾。。我不想粗鲁,但我想说这有点失题了。虽然很多人出于各种原因不喜欢这本书,但是《艰苦学习Python》有一个关于父/子类交互的有用章节,以及3种方法。通常可以看到super用于继承一些属性,然后还设置一些不随父类附带的附加属性。所以在这种情况下,顺序之间是不相关的。仔细看你的问题,我想你应该最后调用super(),但我并不完全明白你在这里要做什么。这一切似乎都有点多余,因此我从中得到的是,在Python中,最好在子类的
\uuuu init\uuuu
末尾调用
super()。\uuuuu init\uuu
而不是在设置子类属性时在开头调用
super()
嗯。。不客气,但我想说那是小姐