Chanelling Guido - dict subclasses

Cameron Simpson cs at zip.com.au
Wed Jan 15 16:42:42 EST 2014


On 15Jan2014 05:03, Tim Chase <python.list at tim.thechases.com> wrote:
> On 2014-01-15 01:27, Steven D'Aprano wrote:
> > class TextOnlyDict(dict):
> >     def __setitem__(self, key, value):
> >         if not isinstance(key, str):
> >             raise TypeError
> >         super().__setitem__(key, value)
> >     # need to override more methods too
> > 
> > 
> > But reading Guido, I think he's saying that wouldn't be a good
> > idea. I don't get it -- it's not a violation of the Liskov
> > Substitution Principle, because it's more restrictive, not less.
> > What am I missing?
> 
> Just as an observation, this seems almost exactly what anydbm does,
> behaving like a dict (whether it inherits from dict, or just
> duck-types like a dict), but with the limitation that keys/values need
> to be strings.

I would expect anydbm to be duck typing: just implementing the
mapping interface and directing the various methods directly to the
DBM libraries.

The comment in question was specificly about subclassing dict.

There is a rule of thumb amongst the core devs and elder Python
programmers that it is a bad idea to subclass the basic types which
I have seen stated many times, but not explained in depth.

Naively, I would have thought subclassing dict to constraint the
key types for some special purpose seems like a fine idea. You'd need
to override .update() as well and also the initialiser. Maybe it
is harder than it seems.

The other pitfall I can see is code that does an isinstance(..,
dict) check for some reason; having discovered that it has a dict
it may behave specially. Pickle? Who knows? Personally, if it is
using isinstance instead of a direct type() check then I think it
should expect to cope with subclasses.

I've subclassed str() a number of times, most extensively as a URL
object that is a str with a bunch of utility methods, and it seems
to work well.

I've subclassed dict a few times, most extensively as the in-memory
representation of record in a multibackend data store which I use
for a bunch of things. That is also working quite well.

The benefit of subclassing dict is getting a heap of methods like
iterkeys et al for free. A from-scratch mapping has a surprising
number of methods involved.

Cheers,
-- 
Cameron Simpson <cs at zip.com.au>

BTW, don't bother flaming me. I can't read.
        - afdenis at lims03.lerc.nasa.gov (Stephen Dennison)



More information about the Python-list mailing list