Python的超级(),究竟发生了什么?

时间:2016-07-04 14:06:25

标签: python

我试图了解在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)调用父类的构造函数#34;实例化我们的子类。因此,我们只有 ONE对象我们的类ElectricCar()。

2)super(),调用父项的构造函数,创建" Car"的对象。 class,然后我们通过" super()。 init (make,model,year)"来调用此对象的构造函数。因此,我们有两个对象:Car()类的一个对象和ElectiricCar类的一个对象,在我们的例子中它们是相同的。

哪一个是正确的? 如果两者都没有,那么请解释一下究竟发生了什么:

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

1 个答案:

答案 0 :(得分:5)

__init__不是构造函数,它是初始化程序。到调用__init__时,对象已经构建(通过__new__)。因此,您只获得一个对象,但它已初始化两次 - 例如,ElectricCar.__init__可能决定在self.model运行后重新初始化Car.__init__

调用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__