我试图了解在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)
答案 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__
。