Python继承和__init__

时间:2012-07-28 18:21:51

标签: python oop

我正在学习Python,而且我发现了一些关于Python如何构造一个令我困惑的子类的东西。

我有一个继承自列表类的类,如下所示。

class foo(list):
    def __init__(self, a_bar):
        list.__init__([])
        self.bar = a_bar

我知道list.__init__([])需要在那里,但我对此感到困惑。在我看来,这一行只会创建一个新的列表对象,然后将其分配给任何东西,所以我怀疑它只会被垃圾收集。 Python如何知道这个列表是我的对象的一部分?我怀疑幕后发生了一些事情,我想知道它是什么。

4 个答案:

答案 0 :(得分:3)

这种多继承安全的方式是:

class foo(list):
    def __init__(self, a_bar):
        super(foo, self).__init__()
        ...

或许可以让你更清楚你正在调用基类ctor。

答案 1 :(得分:2)

通常在子类化和覆盖__init__()函数时执行此操作:

list.__init__(self)

如果您使用的是Python 3,则可以使用super()

super().__init__()

答案 2 :(得分:1)

你部分正确:

list.__init__([]) 

“创建一个新的列表对象。”但是这段代码错了。正确的代码_should_be:

list.__init__(self)

你需要它的原因是因为你继承了list,它拥有它自己的__init__()方法,它(可能)对初始化自身很重要。定义自己的__init__()方法时,您实际上会覆盖同名的继承方法。为了确保父类的__init__()代码也被执行,您需要调用该父类的__init__()

有几种方法可以做到这一点:

#explicitly calling the __init__() of a specific class
#"list"--in this case
list.__init__(self, *args, **kwargs)     

#a little more flexible. If you change the parent class, this doesn't need to change
super(foo, self).__init__(*args, **kwargs) 

有关super()的详情,请参阅this question,有关超级陷阱的指导,请参阅this article

答案 3 :(得分:0)

实际对象不是使用__init__创建的,而是使用__new__创建的。 __init__不是用于创建对象本身,而是用于初始化它 - 即添加属性等。到调用__init__时,__new__已被调用,因此您的示例在您的代码运行之前已经创建了列表。 __init__不应返回任何内容,因为它应该“就地”初始化对象(通过改变它),因此它可以通过副作用来工作。 (请参阅a previous questionthe documentation。)