Subclassing Python's dict

Raymond Hettinger python at rcn.com
Thu Aug 6 17:18:14 EDT 2009


> Xavier Ho wrote:
> > You should subclass collections.UserDict, and not the default dict class.
> > Refer to the collections module.
>
> Xavier, why do you think that is the correct approach? The docs say
> "The need for this class has been largely supplanted by the ability to
> subclass directly from dict (a feature that became available starting
> with Python version 2.2)."

UserDict can be a good choice because the pure python source makes
it clear exactly what needs to be overridden (you can see which
methods are implemented in terms of lower level methods and which
ones access the underlying dict directly.

Another choice is to use DictMixin or MutableMapping and fill-in just
the required abstract methods.  This approach is simple and
flexible.
It allows you to wrap a mapping interface around many different
classes
(a dbm for example).  The disadvantage is that it can be slow.

Subclassing a dict is typically done when the new class has to be
substitutable for real dicts (perhaps an API enforces a check
for instance(x, dict) or somesuch).  As the OP found out, the
dict methods all access the underlying structure directly, so
you will need to override *all* methods that need to have a new
behavior.  The remaining methods are inherited and run at C speed,
so performance may dictate this approach.

So, there you have three ways to do it.  In Py3.1, we used the latter
approach for collections.Counter() -- that gives a high speed on the
inherited methods.  For collections.OrderedDict, a hybrid approach
was used (subclassing from both dict and MutableMapping).  Most of
the work is done by MutableMapping and the dict is inherited so that
the OrderedDict objects would be substitutable anywhere regular
dicts are expected.  And IIRC, there are still some cases of UserDict
being used in the python source (situations where subclassing from
dict wouldn't work as well).


Raymond




More information about the Python-list mailing list