【问题标题】:Python's super() , what exactly happens? [duplicate]Python 的 super() 到底发生了什么? [复制]
【发布时间】:2016-11-06 07:14:26
【问题描述】:

我试图了解当我们在 Python 中实例化子类时创建了哪些对象,例如:

class Car():
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year

class ElectricCar(Car):
     def __init__(self, make, model, year):
          super().__init__(make, model, year)

my_tesla = ElectricCar('tesla', 'model s', 2016)

当我们创建对象 my_tesla 时,我们通过调用该类的构造函数来实例化 ElectricCar 类,该构造函数又调用父类的构造函数。它是如何发生的?现在我有两个猜测:

1) super() 只是对父类的引用,所以我们通过“super().init(make, model, year)”调用父类的构造函数来实例化我们的子类班级。因此,我们的 ElectricCar() 类只有 一个对象

2) super(),调用父类的构造函数,创建“Car”类的对象,然后我们调用这个对象的构造函数,通过“super().init(品牌、型号、年份)”。因此,我们有两个对象:一个 Car() 类的对象和一个 ElectiricCar 类的对象,但在我们的例子中它们是相同的。

哪一个是正确的? 如果两者都不是,请解释一下到底发生了什么:

 super().__init__(make, model, year)

【问题讨论】:

  • 没有。你仍然只有一个对象,ElectricCar。构造函数和其他函数一样。它不会为您“创建”对象 - 在执行构造函数时,该对象已经由底层运行时创建。构造函数只是用来初始化那个新对象。所以调用 super().__init__ 只是运行一个普通的对象方法。该方法是构造函数的事实是无关紧要的。只有当它被对象生成器自动执行时,它才是一个构造函数。

标签: python super


【解决方案1】:

__init__ 不是构造函数,它是初始化器。在调用__init__ 时,对象已经被构造(通过__new__)。所以你只得到一个对象,但它被初始化了两次——例如,ElectricCar.__init__ 可能决定在运行Car.__init__ 之后重新初始化self.model

调用super() 时,会在当前实例的上下文中查找适当的基类。基本上,super().__init__(make, model, year) 在您的示例中可以重写为 Car.__init__(self, make, model, year)

这就是为什么在早期版本的 python 中,调用实际上是 super(ElectricCar, self) - 它查找当前类的基类 (ElectricCar) 并使用当前实例 (self) 就好像它是一个实例代替那个类。

请注意,初始化并不意味着准备对象,而是准备对象的状态。一个对象即使没有实现 __init__ 也是完全正常的。


澄清一下:当你调用ElectricCar()时,实际执行的和这个差不多:

that_object = ElectricCar.__new__()  # this will actually use object.__new__
if isinstance(that_object, ElectricCar):
    ElectricCar.__init__(that_object)
return that_object

这意味着您在调用ElectricCar.__new__ 时拥有一个 对象。对ElectricCar.__init__ 的调用只会修改/初始化该对象。它可以使用其他函数来执行此操作,例如Car.__init__

【讨论】:

  • 那么,这两个类的对象到底是怎么创建的呢?并且通过: super().__init__(make, model, year) 我们只是初始化我们的 ElectricCar 对象?结果是 Car 类的一个对象未​​初始化,而 ElectricCar 类的一个对象已初始化?
  • 只有一个对象被创建,即当你调用ElectricCar()时。 那个对象然后被用作that_object.__init__(),它解析为ElectricCar.__init__(self=that_object),它使用super调用Car.__init__(self=that_object)
猜你喜欢
  • 2021-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-13
  • 2013-11-13
  • 2023-04-04
  • 1970-01-01
相关资源
最近更新 更多