Python的继承和__init__

问题描述:

我在学习Python,我发现了一些关于Python如何构造一个让我困惑的子类。Python的继承和__init__

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

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

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

+3

你从哪里找到这段代码?这是不正确的 – 2012-07-28 18:27:35

实际对象不是用__init__创建的,而是用__new__创建的。 __init__不是用于创建对象本身,而是用于初始化它 - 也就是添加属性等。在调用__init__时,__new__已被调用,因此在您的示例中,该列表在您的代码运行之前已经创建。 __init__不应该返回任何东西,因为它应该初始化“in-place”对象(通过改变它),所以它通过副作用起作用。 (见a previous questionthe documentation。)

你通常继承和重写__init__()功能时做到这一点:

list.__init__(self) 

如果你使用Python 3,你可以使用super()

super().__init__() 

执行多重继承安全的方法是:

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

这可能会让你更清楚地知道你正在调用基类ctor。

+0

它需要多一点MI安全。 – delnan 2012-07-28 18:29:09

+0

@delnan如..? – thebjorn 2012-07-28 18:31:16

+3

如继承树中的所有类同意'__init__'参数使用'super'。看[Python的super()被认为是超级!](http://rhettinger.wordpress。COM/2011/5月26日/超认为超/)。 – delnan 2012-07-28 18:52:54

你是有一定道理:

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

+0

这应该是正确的答案! – 2014-02-11 22:45:54