Skip to content Skip to sidebar Skip to footer

Extending Types By Subclassing In Python

This is extracted from Learning Python 4th edition. Its function is to subclass set using list. But I don't understand line 5 list.__init__([]), please help. The code works even wh

Solution 1:

The code in the book contains an error. I've submitted an errata to O'Reilly books, which you can read along with the authors response on this page (search for 982). Here's a small snippet of his response:

This code line has apparently been present in the book since the 2nd Edition (of 2003--10 years ago!), and has gone unremarked by hundreds of thousands of readers until now

The line list.__init__([]) is missing an argument, and commenting it out makes no difference whatsoever, except speeding up your program slightly. Here's the corrected line:

        list.__init__(self, [])

When calling methods that are not static methods or class methods directly on class objects, the normally implicit first argument self must be provided explicitly. If the line is corrected like this it would follow the good practice that Antonis talks about in his answer. Another way to correct the line would be by using super, which again makes the self argument implicit.

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

The code in the book provides a different empty list ([]) as the self argument, which causes that list to be initialized over again, whereupon it is quickly garbage collected. In other words, the whole line is dead code.

To verify that the original line has no effect is easy: temporarily change [] in list.__init__([]) to a non-empty list and observe that the resulting Set instance doesn't contain those elements. Then insert self as the first argument, and observe that the items in the list are now added to the Set instance.

Solution 2:

You mean this line?

    list.__init__([])

When you override the __init__ method of any type, it's good practice to always call the inherited __init__ method; that is, the __init__ method of the base class. This way you perform initialization of the parent class, and add initialization code specific to the child class.

You should follow this practice even if you are confident that the __init__ of the parent does nothing, in order to ensure compatibility with future versions.

Update: As explained by Lauritz in another answer, the line

    list.__init__([])

is wrong. See his answer and the other answers for more.

Solution 3:

You mean list.__init__([])?

It calls the base initializer from the subclass initializer. Your subclass has replaced the base class initializer with its own.

In this case commenting that out happens to work because the unbound initializer was called with an empty list instead of self and is thus a no-op. This is an error on behalf of the authors, most likely.

But it is a good idea generally to make sure the base class has run its initialization code when you subclass. That way all internal data structures the base class methods rely on have been set up correctly.

Solution 4:

This line is like creating an __init__ constructor in Set class which calls its base class constructor.

You might have already seen this:

classSet(list):
... def__init__(self, *args, **kwargs):
        super(Set, self).__init__(args, kwargs)
        # do something additional here

Post a Comment for "Extending Types By Subclassing In Python"