views:

276

answers:

4

Let's say that I have class, that uses some functionality of dict. I used to composite a dict object inside and provide some access from the outside, but recently thought about simply inheriting dict and adding some attributes and methods that I might require. Is it a good way to go, or should I stick to composition?

+1  A: 

Both are good, but I'd prefer inheriting, as it will mean less code (which is always good as long as it is readable).

Dive into Python has a very relevant example.

On Python 2.2 and prior, you couldn't subclass from built ins directly, so you had to use composition.

class FileInfo(dict):                  
   "store file metadata"
   def __init__(self, filename=None): 
       self["name"] = filename
  1. The first difference is that you don't need to import the UserDict module, since dict is a built-in datatype and is always available. The second is that you are inheriting from dict directly, instead of from UserDict.UserDict.
  2. The third difference is subtle but important. Because of the way UserDict works internally, it requires you to manually call its __init__ method to properly initialize its internal data structures. dict does not work like this; it is not a wrapper, and it requires no explicit initialization.
voyager
+4  A: 

Inheritance is very often abused. Unless your class is meant to be used as a generic dictionary with extra functionality, I would say composition is the way to go.

Saving forwarding calls is usually not a good enough reason for choosing inheritance.

From the Design Pattern book:

Favor object composition over class inheritance

Ideally you shouldn't have to create new components to achieve reuse. You should be able to get all the functionality you need by assembling existing components through object composition. But this is rarely the case, because the set of available components is never quite rich enough in practice. Reuse by inheritance makes it easier to make new components that can be composed with old ones. Inheritance and object composition thus work together.

Nevertheless, our experience is that designers overuse inheritance as a reuse technique and designs are often made more reusable (and simpler) by depending more on object composition."

The entire text is here: http://blog.platinumsolutions.com/node/129

Philippe Beaudoin
Remember that Python is extremely flexible, object composition is great, but if you are just mapping one to one to another object, inheritance is the way to go.
voyager
I don't think it has anything to do with Python being flexible, it's a design issue. If you are mapping all methods of one object to the other, then you are probably building a dictionary: use inheritance. But when the original poster writes "I have class, that uses some functionality of dict", it hints at the fact that class is not meant to be used as a dictionary.
Philippe Beaudoin
+2  A: 

You really have to weigh out the cost and scope of what you're trying to do. Inheriting from dict because you want dictionary-like behavior is quick and easy but prone to limitations such as causing objects created from your class to be unhashable.

So for example, if you are going to need to serialize (i.e. pickle) the objects, but also want dictionary-like behavior, then obviously you can't inherit directly from dict and you'll need to compose the parts of the functionality you desire to make that happen.

jathanism
+1  A: 

Should isinstance(my_object, dict) return True or False? In other words, if you accidentally give one of the objects to something that wants a dict, should it blithely try to use it as a dict? Probably not, so use composition.

Daniel Newby
Helping people typecheck isn't necessarily a good thing.
Mike Graham
Type checking has its place. For instance, if you had pretty printer function that understood dicts, you'd probably not want it printing your enhanced object as if it were a dict. Nor would you want to use the type check-free alternative: monkey patching dict.
Daniel Newby