__init __()应该调用父类的__init __()吗?

Geo*_*lly 120 python

我在Objective-C中使用它我有这个结构:

- (void)init {
    if (self = [super init]) {
        // init class
    }
    return self;
}
Run Code Online (Sandbox Code Playgroud)

Python是否也应该调用父类的实现__init__

class NewClass(SomeOtherClass):
    def __init__(self):
        SomeOtherClass.__init__(self)
        # init class
Run Code Online (Sandbox Code Playgroud)

对于__new__()和,这也是真/假__del__()吗?

编辑:有一个非常类似的问题:Python中的继承和覆盖__init__

Ano*_*non 133

如果__init__除了在当前课程中所做的事情之外你还需要超级的东西,__init__,你必须自己调用它,因为这不会自动发生.但如果你不需要任何超级的东西,__init__,就不需要打电话.例:

>>> class C(object):
    def __init__(self):
        self.b = 1


>>> class D(C):
    def __init__(self):
        super().__init__() # in Python 2 use super(D, self).__init__()
        self.a = 1


>>> class E(C):
    def __init__(self):
        self.a = 1


>>> d = D()
>>> d.a
1
>>> d.b  # This works because of the call to super's init
1
>>> e = E()
>>> e.a
1
>>> e.b  # This is going to fail since nothing in E initializes b...
Traceback (most recent call last):
  File "<pyshell#70>", line 1, in <module>
    e.b  # This is going to fail since nothing in E initializes b...
AttributeError: 'E' object has no attribute 'b'
Run Code Online (Sandbox Code Playgroud)

__del__是同样的方式,(但要谨慎依赖于__del__最终确定 - 考虑通过with语句来代替).

我很少使用__new__. 我做的所有初始化__init__.

  • super().__ init __()仅适用于Python 3.在Python 2中,你需要super(D,self).__ init __() (11认同)
  • “如果你需要 super 的 __init__ 中的某些东西...” - 这是一个非常有问题的陈述,因为这不是你/子类是否需要“某些东西”的情况,而是基类是否需要某些东西才能成为有效的东西基类实例并正常工作。作为派生类的实现者,基类的内部结构是您不能/不应该知道的事情,即使您知道,因为您编写了两者或内部结构已记录,基类的设计将来可能会发生变化,并由于编写得不好而破坏派生类。因此,请始终确保基类已完全初始化。 (4认同)
  • D(C)类的定义必须更正为"super(D,self).__ init __()`` (3认同)

eyq*_*uem 92

在Anon的回答中:
"如果__init__除了当前课程中的内容之外你还需要超级的东西__init__,你必须自己调用它,因为这不会自动发生"

这是令人难以置信的:他的措辞完全与继承原则相反.


并不是"来自超级__init__ (...)的东西不会自动发生",而是它会自动发生,但它不会发生,因为基类' __init__被派生字符串的定义所覆盖__init__

那么,为什么定义一个derived_class' __init__,因为它覆盖了当某人诉诸继承时的目标?

这是因为需要定义一些未在基类中完成的东西__init__,并且获得它的唯一可能性是将其执行放在派生类__init__函数中.
换句话说,如果后者没有被覆盖,除了在base-classe中自动完成的内容之外,还需要基类中的某些内容__init____init__.
不相反.


然后,问题是__init__在实例化时不再激活基类中存在的期望指令.为了抵消这种失活,需要一些特殊的东西:显式调用基类' __init__,以便保持,不添加,由基类执行的初始化' __init__.这正是官方文件中所说的:

派生类中的重写方法实际上可能希望扩展而不是简单地替换同名的基类方法.有一种直接调用基类方法的简单方法:只需调用BaseClassName.methodname(self,arguments).
http://docs.python.org/tutorial/classes.html#inheritance

这就是故事:

  • 当目标是保持基类执行的初始化,即纯继承时,不需要任何特殊的东西,必须避免__init__在派生类中定义一个函数

  • 当目标是REPLACE由基类执行的初始化时,__init__必须在derived-class中定义

  • 当目标是将进程添加到基类执行的初始化时,__init__ 必须定义派生类' ,包括对基类的显式调用__init__


我在Anon的职位上感到惊讶的不仅仅是他表达了继承理论的相反,而且已经有5个人在没有转过头的情况下顺利过关,而且在2年内没有人做出反应一个线程,其有趣的主题必须经常阅读.

  • 你在Aaron引用的句子中错过了"另外"的重要单词.Aaron的陈述是完全正确的,并且与你最终说的相符. (3认同)
  • "我确信这篇文章会被投票赞成......"主要问题是你参加聚会的时间有点晚了,而且大多数人可能不会读到前几个答案.通过+1的方式很好的解释 (2认同)
  • 这是使 python 的设计选择有意义的第一个解释。 (2认同)

Mar*_*wis 61

在Python中,调用超类' __init__是可选的.如果你调用它,那么它是否也可以使用super标识符,或者是否显式命名超类:

object.__init__(self)
Run Code Online (Sandbox Code Playgroud)

在对象的情况下,调用super方法并不是绝对必要的,因为super方法是空的.同样的__del__.

另一方面,对于__new__,你应该确实调用super方法,并使用它的返回作为新创建的对象 - 除非你明确想要返回不同的东西.

  • 在旧式类中,如果超类实际上定义了__init__(通常不会定义),则只能调用super __init__.因此,人们通常会考虑调用超级方法,而不是原则上这样做. (5认同)

Sil*_*ost 19

编辑 :(代码更改后)
我们无法告诉您是否需要调用您的父母__init__(或任何其他功能).如果没有这样的召唤,遗传显然会有效.这一切都取决于你的代码的逻辑:例如,如果你所有的__init__都在父类中完成,你可以完全跳过子类__init__.

考虑以下示例:

>>> class A:
    def __init__(self, val):
        self.a = val


>>> class B(A):
    pass

>>> class C(A):
    def __init__(self, val):
        A.__init__(self, val)
        self.a += val


>>> A(4).a
4
>>> B(5).a
5
>>> C(6).a
12
Run Code Online (Sandbox Code Playgroud)


Vin*_*jip 5

没有硬性规定。类的文档应指明子类是否应调用超类方法。有时您想完全替换超类行为,而在其他时候则增加它——即在超类调用之前和/或之后调用您自己的代码。

更新:相同的基本逻辑适用于任何方法调用。构造函数有时需要特殊考虑(因为它们经常设置决定行为的状态)和析构函数,因为它们并行构造函数(例如在资源分配中,例如数据库连接)。但同样的情况也可能适用于render()小部件的方法。

进一步更新:什么是 OPP?你是说OOP吗?否-一个子类经常需要知道一些关于超类的设计。不是内部实现细节——而是超类与其客户(使用类)之间的基本契约。这不会以任何方式违反 OOP 原则。这就是为什么protected通常在 OOP 中是一个有效概念的原因(当然,在 Python 中不是)。