I was recently going over a coding problem I was having and someone looking at the code said that subclassing list was bad (my problem was unrelated to that class). He said
There are no benefits to subclassing list
. None of the methods will use any methods you override, so you can have unexpected bugs. Further, it's very often confusing doing things like self.append
instead of self.foos.append
or especially self[4]
rather than self.foos[4]
to access your data. You can make something that works exactly like a list or (better) howevermuch like a list you really want while just subclassing object
.
The abstract base classes provided in the collections module, particularly MutableSequence
, can be useful when implementing list-like classes. These are available in Python 2.6 and later.
With ABCs you can implement the "core" functionality of your class and it will provide the methods which logically depend on what you've defined.
For example, implementing __getitem__
in a collections.Sequence
-derived class will be enough to provide your class with __contains__
, __iter__
, and other methods.
You may still want to use a contained list object to do the heavy lifting.
Nick is correct. Also, while I can't speak to Python, in other OO languages (Java, Smalltalk) subclassing a list is a bad idea. Inheritance in general should be avoided and delegation-composition used instead.
Rather, you make a container class and delegate calls to the list. The container class has a reference to the list and you can even expose the calls and returns of the list in your own methods. This adds flexibility and allows you to change the implementation (a different list type or data structure) later w/o breaking any code. If you want your list to do different listy-type things then your container can do this and use the plain list as a simple data structure. Imagine if you had 47 different uses of lists. Do you really want to maintain 47 different subclasses? Instead you could do this via the container and interfaces. One class to maintain and allow people to call your new and improved methods via the interface(s) with the implementation remaining hidden.
I think the first question I'd ask myself is, "Is my new object really a list?". Does it walk like a list, talk like a list? Or is is something else?
If it is a list, then all the standard list methods should all make sense.
If the standard list methods don't make sense, then your object should contain a list, not be a list.
In old python (2.2?) sub-classing list was a bad idea for various technical reasons, but in a modern python it is fine.