简体   繁体   中英

Python Inheritance and __init__

I'm learning Python and I've found something about how Python constructs a sub class which confuses me.

I have a class that inherits from the list class as follows.

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

I know that list.__init__([]) needs to be there but I'm confused about it. It seems to me that this line will just create a new list object and then assign it to nothing, so I would suspect that it would just get garbage collected. How does Python know that this list is part of my object? I suspect that there is something happening behind the scenes and I'd like to know what it is.

The multiple-inheritance-safe way of doing it is:

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

which, perhaps, makes it clearer that you're calling the baseclass ctor.

You usually do this when subclassing and overriding the __init__() function:

list.__init__(self)

If you're using Python 3, you can make use of super() :

super().__init__()

You're partly right:

list.__init__([]) 

"creates a new list object." But this code is wrong. The correct code _should_be:

list.__init__(self)

The reason you need it to be there is because you're inheriting from a list that has it's own __init__() method where it (presumably) does important to initialize itself. When you define your own __init__() method, you're effectively overriding the inherited method of the same name. In order to make sure that the parent class's __init__() code is executed as well, you need to call that parent class's __init__() .

There are several ways of doing this:

#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) 

For more on super() see this question , for guidance on the pitfalls of super, see this article .

The actual object is not created with __init__ but with __new__ . __init__ is not for creating the object itself but for initializing it --- that is, adding attributes, etc. By the time __init__ is called, __new__ has already been called, so in your example the list was already created before your code even runs. __init__ shouldn't return anything because it's supposed to initialize the object "in-place" (by mutating it), so it works by side-effects. (See a previous question and the documentation .)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM