代码之家  ›  专栏  ›  技术社区  ›  barciewicz

我是否需要手动将属性从超类的“uuu init_uuuu”传递到子类的“uu init_uuuu”,即使我使用“super()”?

  •  1
  • barciewicz  · 技术社区  · 6 年前

    在下面的例子中——摘自《Python崩溃教程》——我们为什么要通过 make , model year 对子类 __init__ 方法?

    不是 super() 应该已经将这些参数转移到子类的 爱因斯坦 方法是否自动?

    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 回复  |  直到 6 年前
        1
  •  0
  •   r.ook jpp    6 年前

    虽然你的措辞不太正确(事实上这些论点是从 子类 超类 ,答案是 ,您需要为手动传递参数 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__() . 在这种情况下,如果你 手动将任何参数传递给 super().__init() 翻译会抱怨超类的 爱因斯坦 方法不接受任何参数。你很快就会明白为什么这看起来没用,但是 here's a related question on properly inheriting from str / int (如有必要)。

        2
  •  2
  •   bruno desthuilliers    6 年前

    为什么我们要把品牌、型号和年份传递给子类 初始化 方法?

    不然它会怎么把它们传给它的超类呢?

    super()是否应该已经将这些参数传输到子类的 初始化 方法是否自动?

    不。 Super() 返回MRO中下一个类的代理(cf How does Python's "super" do the right thing? 更多关于 super 物体等)。它不是“转移”到子类,而是使用 super() 调用父级的实现。

    注意在这个例子中, ElectricCar __init__ 方法是完全无用的-它只委托给父级,而不做其他任何操作,因此您只需移除它和父级的 爱因斯坦 将自动使用。要点 超级() 在子类中专门化父方法时调用父方法,即:

    class Parent():
       def __init__(self, foo):
           self.foo = foo
    
    
    class Child(Parent):
       def __init__(self, foo):
           super().__init__(foo)
           # doing something more...
           self.bar = 42