我读了this question得分最高的答案,它说我们应该打电话给超级班级' __init__
如果我们需要,而且我们不必这样做。但我的问题更多的是关于惯例。
我通常,作为一般规则,总是调用超类'我班上的__init__
' __init__
,无论我目前是否需要'该方法的功能?
答案 0 :(得分:2)
有些类需要调用__init__
方法才能工作。他们使用他们需要的__init__
方法集属性。
示例:
class one ():
def __init__ (self):
self.number = 20
def show_number(self):
return self.number
如果您继承上述类,则需要调用其__init__
方法以定义属性number
。如果未调用__init__
方法,则在尝试调用方法show_number
时可能会出错。
至于语法,如果继承类的__init__
方法没有任何反应,则不需要调用它。如果您认为不调用__init__
方法会让其他人感到困惑,您可以随时用评论来解释您的推理。即使你不需要它也不会对它进行任何伤害。
答案 1 :(得分:1)
这个答案有一些贬低,因为贬低者在焦点上不同意我,也许在“惯例”意味着什么。在编写代码时,我认为我们大多同意实际的做法。
不。你不应该通常,作为一般规则,总是在你的班级__init__
中调用超类的__init__
,无论您当前是否“需要”该方法中的功能。
但请注意,我强调的是最后一句,从“不论”开始,而 是我的“不”答案的意思。你不应该在你的Python代码中抛出一些东西“只是因为有人告诉你”或“只是因为这似乎是大多数人正在做的事情。”
如果需要,您应该包含一些内容,如果不需要,则不包含内容。
通常情况下,有人会认为通常的情况是,你做想要调用你的超类的__init__
方法子类的__init__
方法。 我大部分时间都是这样做的。
但为什么?
至关重要的是,由于某些“惯例”,它不。我这样做是因为我的子类通常需要与超类相同的初始化,再加上一些额外的自定义。请注意,额外的自定义是首先覆盖__init__
的全部原因。如果您的子类的初始化与超类的初始化相同,那么您根本不应该定义自己的__init__
。
在Python中编写一些不需要的东西。有些人有他们自己的约定来包含不必要的东西;也许是以“防御性编程”的名义,或者因为它们被用于需要更多样板的不同语言。
Python的约定来自于您可以选择多种方式表达有用的东西。的确,Python并不强调简洁性。但这并不意味着它也强调冗长。所以,我要补充一下,以防不清楚:
通常 ,作为一般规则,始终避免不必要的样板代码。 (而不只是在Python中。)
[对于那些认为“通常总是”这句话很尴尬或荒谬的人:我完全同意,但我试图通过重复提问者自己选择的词来强调我的观点。]
答案 2 :(得分:1)
是。通常,您应该从子类的__init__
方法调用超类的__init__
。这不是Python约定,而是OO最佳实践建议您应该做的事情(鉴于您恰好使用的语言,该决定由您自己决定):
超类不知道子类,但是希望子类知道其继承的超类的语义。最终,由子类来维持真实的sub-typing的一致行为(不幸的是,Python语言几乎没有帮助程序员)。作为子类实现者,您可以决定是否需要调用超类__init__
,就像您可以决定是否/不需要/想要调用重写的任何方法的超类实现一样。但是,对象的初始化往往是许多对象生命周期中非常重要的一步。在对象被初始化之前,可以断言该对象实际上不是给定类的实例。在所有合理的OO语言中,这是一个隐含且重要的后置条件,当您实例化一个对象时,某些事情已经发生,我们可以依赖,这些事情已经发生,初始化(或其他情况下的“构造”)语言)是中心问题-是涉及复杂的参数验证和计算值生成,还是仅仅是空操作。因此,如果您不调用super的初始值设定项,则最好确切地知道您要做什么。
作为一般规则调用super的__init__
的另一个参数是,如果您没有编写超类,或者您没有严格控制版本,则__init__
的实现将来可能会更改(确实我不确定是否可以在__init__
中添加一些东西来引起主要版本变更吗?我敢打赌,即使是技术上他们应该这么做,很多人也不会为此而改变主要版本编号。因此,如果您调用超类的__init__
,则代码不大可能因超类实现的更新而中断。
更新:在回答此问题之前,应先阅读linked question。那里的大多数答案都与这里的普遍情绪相呼应-也许不是像我一样以相同的术语或强烈支持将__init__()
称为一般规则。但我会将这个答案留给其他人。