为什么在这种情况下插入超类的__init __()?

时间:2013-08-19 07:23:27

标签: python class initialization

我现在正在阅读HeadFirstPython,并且有一个关于类的例子。

>>> class NamedList(list):
>>>    def __init__(self, a_name):
>>>        list.__init__([])
>>>        self.name = a_name

在这种情况下,为什么使用语句list.__init__([])? 而且也无法理解为什么它包括空[]

2 个答案:

答案 0 :(得分:2)

通常,因为调用您继承的类的初始化程序是良好做法

但是,作者似乎已将self替换为空列表;我用过其中一个:

super(NamedList, self).__init__()
super(NamedList, self).__init__([])

或者至少提供了一个明确的self参数:

list.__init__(self)

在这种情况下,您正在继承list;它的初始化程序采用了一个初始的元素列表,但是你自己的初始化程序只需要a_name,因此超类初始化程序会传递一个显式的空列表。

list.__init__()方法只是清除和扩展;它相当于self.clear(); self.extend(argument),重置它的大小,并在多次调用__init__()的情况下使其可重复使用。

将新的列表对象传递给list初始化程序会使调用完全无用且无操作;这是一个错误,必须由技术审查下滑。

答案 1 :(得分:0)

本书中的代码包含错误。第list.__init__([])错过了一个参数,并且将其注释掉没有任何区别,只是稍微加快了程序的速度。

我在阅读你的问题时几乎无法相信,因为我最近回答了similar question来自另一本书(“学习Python”)的代码,其中包含完全相同的错误

这是更正后的行:

        list.__init__(self, [])

直接在类对象上调用方法(非静态方法或类方法)时,必须明确提供通常隐式的第一个参数self。纠正这一行的另一种方法是使用super,这会隐含self参数。

        super(NamedList, self).__init__([])

[]参数在任何一种情况下都是不必要的,但编写显式代码是一个好习惯,在这种情况下它会传达我们真正希望列表为空的。

本书中的代码是提供一个空列表([])作为self参数。这会导致 列表被初始化(重复),之后很快就会收集垃圾,因为没有任何对它的引用保留在任何地方。换句话说,整行都是死代码。

要验证原始行没有效果很简单:暂时将[]中的list.__init__([])更改为非空列表,并观察生成的NamedList实例不包含这些元素。然后插入self作为第一个参数,并观察列表中的项目现在已添加到NamedList实例。