0

This is from the book head first python (pg 208 chapter 6). Initially I saw an example in the book of the initialisation of the subclass as so:

class AthleteList(list):
    def __init__(self, a_times=[]):
        list.__init__([])
        self.extend(a_times)

When I came to writing my own version I thought I could skip the extend step:

class AthleteList(list):
    def __init__(self, a_times=[]):
        list.__init__(a_times)

When it comes to printing the list:

test = AthleteList([1,2,3])
print(test)

The output is [], so there is something wrong with the initialisation. When searching around, in every case I found I saw it necessary to initialise the superclass by explicitly passing self:

class AthleteList(list):
    def __init__(self, a_times=[]):
        list.__init__(self, a_times)

Which makes more sense: the list superclass needs the object itself passed as an argument so that it can initialise its list values. Except why wasn't self needed in the very first example (which does actually work)? Even if I am initialising it with an empty list I still surely need to pass the self object so that self's list is made empty. I don't even need to initialise it to the empty list first, it seems to do it by default, and I can just extend later:

class AthleteList(list):
    def __init__(self, a_times=[]):
        self.extend(a_times)
Community
  • 1
  • 1
SergeantPenguin
  • 843
  • 7
  • 16
  • You saw `def __init__(self, a_times=[])` in a book? If so you should consider changing a book. http://stackoverflow.com/documentation/python/3553/common-pitfalls/12258/mutable-default-argument#t=201612281429272429582 – DeepSpace Dec 28 '16 at 14:29
  • 1
    As I see it, `AthleteList` is of type `list` and therefore `[]` is used instead of `self` to initialize the parent object (which constructor does not need any arguments). But in my eyes this is very, very unclean. Try `list.__init__([1, 2, 3])` in your first code snippet and create the object with an emtpy `a_times`. The values will not be shown. – ppasler Dec 28 '16 at 14:37
  • inheriting from a list is easier with [`UserList`](https://docs.python.org/3/library/collections.html?highlight=namedtuple#collections.UserList). here everything works as expcected. – hiro protagonist Dec 28 '16 at 14:47
  • For reference, in case anyone's interested, the page in question is [here](https://cdn.pbrd.co/images/fhx27wo1y.png). The book's treatment of inheritance beyond that page is sketchy to say the least, and I have to agree with @DeepSpace that OP should look to [other, better resources](http://sopython.com/wiki/What_tutorial_should_I_read%3F). – Zero Piraeus Dec 28 '16 at 15:14

1 Answers1

1

this is probably the safest way to subclass list; use UserList as base class and things work as expected:

from collections import UserList

class AthleteList(UserList):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

athlete_list = AthleteList((1, 2, 3))
print(athlete_list)  # -> [1, 2, 3]

that admittedly does not answer all your questions but may be a starting point.

here is a more in-depth answer about that: https://stackoverflow.com/a/25464724/4954037 .

Community
  • 1
  • 1
hiro protagonist
  • 44,693
  • 14
  • 86
  • 111