Chanelling Guido - dict subclasses

Ned Batchelder ned at nedbatchelder.com
Tue Jan 14 21:04:22 EST 2014


On 1/14/14 8:27 PM, Steven D'Aprano wrote:
> Over on the Python-Dev mailing list, there is an ENORMOUS multi-thread
> discussion involving at least two PEPs, about bytes/str compatibility.
> But I don't want to talk about that. (Oh gods, I *really* don't want to
> talk about that...)
>
> In the midst of that discussion, Guido van Rossum made a comment about
> subclassing dicts:
>
>      [quote]
>      From: Guido van Rossum <guido at python.org>
>      Date: Tue, 14 Jan 2014 12:06:32 -0800
>      Subject: Re: [Python-Dev] PEP 460 reboot
>
>      Personally I wouldn't add any words suggesting or referring
>      to the option of creation another class for this purpose. You
>      wouldn't recommend subclassing dict for constraining the
>      types of keys or values, would you?
>      [end quote]
>
> https://mail.python.org/pipermail/python-dev/2014-January/131537.html
>
> This surprises me, and rather than bother Python-Dev (where it will
> likely be lost in the noise, and certain will be off-topic), I'm hoping
> there may be someone here who is willing to attempt to channel GvR. I
> would have thought that subclassing dict for the purpose of constraining
> the type of keys or values would be precisely an excellent use of
> subclassing.
>
>
> 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?
>
>

One problem with it is that there are lots of ways of setting values in 
the dict, and they don't use your __setitem__:

 >>> tod = TextOnlyDict()
 >>> tod.update({1: "haha"})
 >>>

This is what you're getting at with your "need to override more methods 
too", but it turns out to be a pain to override enough methods.

I don't know if that is what Guido was getting at, I suspect he was 
talking at a more refined "principles of object design" level rather 
than "dicts don't happen to work that way" level.

Also, I've never done it, but I understand that deriving from 
collections.MutableMapping avoids this problem.

-- 
Ned Batchelder, http://nedbatchelder.com




More information about the Python-list mailing list