在以下示例(摘自Python Crash课程)中,为什么我们将make
,model
和year
传递给子类__init__
方法?
super()
是否应该已经将这些参数自动转移到子类的__init__
方法中?
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)
答案 0 :(得分:2)
我们为什么要将make,model和year传递给子类 init 方法?
它将如何将它们传递给超类?
super()是否应该已经将这些参数自动传输到子类的 init 方法中?
不。 Super()
返回MRO中下一个类的代理(有关super
对象的更多信息,请参见How does Python's "super" do the right thing?)。而且不是“转移”到“子类”,而是使用super()
调用父类的实现的子类。
请注意,在此示例中,ElectricCar
的{{1}}方法是完全没有用的-它仅委托给父对象,而没有其他操作,因此您可以删除它和父对象的{{1 }}将会自动使用。 __init__
的重点是在子类中专门化父类的方法时调用它,即:
__init__
答案 1 :(得分:0)
虽然措辞不太正确(参数实际上是从子类传递给超类),但答案是是 ,您需要为super().__init__(*args, **kwargs)
手动传递参数。否则,您会遇到TypeError
抱怨缺少必需的位置/关键字参数。
在您的示例中,似乎没有必要but you trimmed a key line after the super().__init__()
:
class ElectricCar(Car):
def __init__(self, make, model, year):
super().__init__(make, model, year)
self.battery = Battery()
由于__init__
不具有属性ElectricCar
,因此必须在子类Car
中重新定义battery
。
注意,但是对于不可变的超类,您不需要传递任何参数:
class Foo(int):
def __init__(self, value):
self.value = value
super().__init__()
它只会像__new__()
那样使用您的子类参数。在这种情况下,如果您 did 手动将任何参数传递给super().__init()
,则解释器将抱怨超类的__init__
方法不接受任何参数。您可以快速了解为什么这似乎没用,但是here's a related question on properly inheriting from str
/int
(如有必要)。