【问题标题】:How to call Base Class's __init__ method from the child class? [duplicate]如何从子类调用基类的 __init__ 方法? [复制]
【发布时间】:2013-10-12 21:49:39
【问题描述】:

如果我有一个 python 类:

class BaseClass(object):
#code and the init function of the base class

然后我定义一个子类如:

class ChildClass(BaseClass):
#here I want to call the init function of the base class

如果基类的 init 函数接受一些我将它们作为子类的 init 函数的参数的参数,我如何将这些参数传递给基类?

我写的代码是:

class Car(object):
    condition = "new"

    def __init__(self, model, color, mpg):
        self.model = model
        self.color = color
        self.mpg   = mpg

class ElectricCar(Car):
    def __init__(self, battery_type, model, color, mpg):
        self.battery_type=battery_type
        super(ElectricCar, self).__init__(model, color, mpg)

我哪里错了?

【问题讨论】:

  • 你的格式不对,是复制粘贴的问题吗? Python 会以错误的格式咆哮。
  • @Mingyu 格式不对?你的意思是缩进还是我在这里遗漏了什么?
  • 是的..我的意思是缩进。请看下面我的回答。
  • 不要在 python 3 中使用派生类名(伪代码):super().__init__(args...)

标签: python python-2.7 inheritance constructor


【解决方案1】:

你可以像这样调用超类的构造函数

class A(object):
    def __init__(self, number):
        print "parent", number

class B(A):
    def __init__(self):
        super(B, self).__init__(5)

b = B()

注意:

这仅在父类继承object时有效

【讨论】:

  • 不要使用派生类名在python 3中这样做(伪代码):super().__init__(args...)
【解决方案2】:

你可以使用super(ChildClass, self).__init__()

class BaseClass(object):
    def __init__(self, *args, **kwargs):
        pass

class ChildClass(BaseClass):
    def __init__(self, *args, **kwargs):
        super(ChildClass, self).__init__(*args, **kwargs)

你的缩进不正确,修改后的代码如下:

class Car(object):
    condition = "new"

    def __init__(self, model, color, mpg):
        self.model = model
        self.color = color
        self.mpg   = mpg

class ElectricCar(Car):
    def __init__(self, battery_type, model, color, mpg):
        self.battery_type=battery_type
        super(ElectricCar, self).__init__(model, color, mpg)

car = ElectricCar('battery', 'ford', 'golden', 10)
print car.__dict__

这是输出:

{'color': 'golden', 'mpg': 10, 'model': 'ford', 'battery_type': 'battery'}

【讨论】:

  • 如果您将BaseClass 传递给super,它将跳过BaseClass 并调用object.__init__,这几乎肯定不是您想要的。
  • 同时,OP 代码的唯一问题是他的缩进,解释 super(即使你解释正确,但你没有)没有帮助,特别是考虑到他已经以完全相同的方式使用它;事实上,它的字符是相同的。
  • 谢谢,@abarnert。最初,他没有发布他的代码,他提出的问题是标题中的问题。
  • 您的回答获得最高票数。您应该真正参考如何通过 super().__init__(args) 不使用派生类名称
  • @CharlieParker 你能扩展一下吗?我们应该做什么?
【解决方案3】:

正如明宇指出的,格式有问题。除此之外,我强烈建议在调用super()不要使用派生类的名称,因为这会使您的代码不灵活(代码维护和继承问题)。在 Python 3 中,请改用 super().__init__。这是合并这些更改后的代码:

class Car(object):
    condition = "new"

    def __init__(self, model, color, mpg):
        self.model = model
        self.color = color
        self.mpg   = mpg

class ElectricCar(Car):

    def __init__(self, battery_type, model, color, mpg):
        self.battery_type=battery_type
        super().__init__(model, color, mpg)

感谢 Erwin Mayer 指出将 __class__ 与 super() 一起使用时的问题

【讨论】:

  • 您能否对“不使用派生类名称”的建议做出任何解释?
  • @jwg 我更新了答案以解释为什么 class 是更好的选择。
  • @CraigFinch 使用 self.__class__ 似乎不是一个好主意。在 Python 3 中,您可以简单地使用 super().__init__
  • Py3 优于 Py2 的另一个原因。 (作为3.4出来后才来python的人)
【解决方案4】:

如果您使用的是 Python 3,建议简单地调用 super() 而不带任何参数:

class Car(object):
    condition = "new"

    def __init__(self, model, color, mpg):
        self.model = model
        self.color = color
        self.mpg   = mpg

class ElectricCar(Car):
    def __init__(self, battery_type, model, color, mpg):
        self.battery_type=battery_type
        super().__init__(model, color, mpg)

car = ElectricCar('battery', 'ford', 'golden', 10)
print car.__dict__

不要使用 class 调用 super,因为它可能会导致按照 this answer 的无限递归异常。

【讨论】:

  • 只是好奇为什么这个问题的所有答案都是在调用 super init 方法之前设置 self.battery_type 。在修改对象中的任何内容之前调用 super init 不是更好的做法,因此首先完全初始化基类吗?还是我在这里遗漏了什么?
猜你喜欢
  • 2017-12-13
  • 1970-01-01
  • 2018-10-15
  • 2015-07-15
  • 2011-01-05
  • 1970-01-01
  • 2016-10-05
  • 1970-01-01
  • 2013-12-19
相关资源
最近更新 更多