即使我使用“ super()”,我也需要手动将属性从超类的“ __init__”传递到子类的“ __init__”吗?

时间:2018-12-28 14:42:57

标签: python

在以下示例(摘自Python Crash课程)中,为什么我们将makemodelyear传递给子类__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)

2 个答案:

答案 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(如有必要)。