views:

85

answers:

4

Hi,

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 that you shouldn't do it and that it came with a bunch of bad side effects. Is this true?

I'm asking if list is generally bad to subclass and if so, what are the reasons. Alternately, what should I consider before subclassing list in Python?

+5  A: 

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.

Nick Craig-Wood
+1 Only inherit when it really makes 100% sense, otherwise compose.
delnan
As to side effects, he was a bit out of date? The data is contained in a list, but there are a lot of other specific methods I need to throw over the top in order to do a number of things.
Edward Williams
yes, inherit for "is-a" relationships, compose for pretty much everything else.
Spike Gronim
+4  A: 

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.

Joe
+3  A: 

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.

intuited
+3  A: 

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.

Mike Graham
What if we want to add an attribute to a list? For example, suppose that we have mylist = []. We want something like mylist.x = 3.
Selinap