我现在正在阅读 HeadFirstPython 并且有一个关于类的示例。
>>> class NamedList(list):
>>> def __init__(self, a_name):
>>> list.__init__([])
>>> self.name = a_name
在这种情况下,为什么要list.__init__([])
使用该语句?也无法理解为什么它包括空[]
。
我现在正在阅读 HeadFirstPython 并且有一个关于类的示例。
>>> class NamedList(list):
>>> def __init__(self, a_name):
>>> list.__init__([])
>>> self.name = a_name
在这种情况下,为什么要list.__init__([])
使用该语句?也无法理解为什么它包括空[]
。
通常,因为调用要继承的类的初始化程序是一种很好的做法。
但是,作者似乎已经替换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
初始化程序会使调用完全无用且无操作;这是一个技术审查肯定漏掉的错误。
书中的代码包含错误。该行缺少一个参数list.__init__([])
,并且将其注释掉没有任何区别,只是稍微加快了您的程序。
当我读到你的问题时,我几乎不敢相信,因为我最近回答了关于另一本书(“学习 Python”)中代码的类似问题,其中包含完全相同的错误。
这是更正后的行:
list.__init__(self, [])
当直接在类对象上调用方法(不是静态方法或类方法)时,通常隐式的第一个参数self
必须显式提供。更正该行的另一种方法是使用super
,这使self
参数隐含。
super(NamedList, self).__init__([])
在这两种情况下都不需要该[]
参数,但编写显式代码是一个好习惯,在这种情况下,它表明我们确实希望列表为空。
书中的代码所做的是提供一个空列表 ( []
) 作为self
参数。这会导致该列表被初始化(再次),之后它很快就会被垃圾收集,因为任何地方都没有对它的引用。换句话说,整行都是死代码。
要验证原始行没有效果很容易:暂时更改[]
为非list.__init__([])
空列表并观察结果NamedList
实例不包含这些元素。然后插入self
作为第一个参数,并观察列表中的项目现在已添加到NamedList
实例中。