[Python-ideas] should `dict` supply a default `__missing__` implementation?
Ethan Furman
ethan at stoneleaf.us
Wed Jul 6 01:51:15 EDT 2016
On 07/05/2016 10:11 PM, Matt Gilson wrote:
> This discussion has my brain all twisted up... I'm going to try to work
> my way through it to make some sense of what we're saying here.
>
> 1. It is pretty easy to provide a subclass with a base `__missing__`
> implementation, so why should python be responsible for providing
> that behavior?
> 2. We don't want to encourage subclassing `dict`, so let's not make
> working with `__missing__` slightly nicer (see 1.)
> 3. Would adding `__missing__` to `dict` actually make working with it
> slightly nicer anyway?
> 4. Other places in the standard library for creating mappings easily
> (`UserDict` and `collections.Mapping`) do not support
> `__missing__``, but it is easy to build that functionality yourself
> (see 1. and example code below)
>
> Let me know if I left anything out or misrepresented any of the comments
> ... It definitely wasn't my intent.
> As I see it, there are three paths forward.
>
> * Do nothing. The status quo probably only surprises one or two users
> a year, so lets not rock the boat. Additionally, we can't add
> _everything_ everywhere. Things just become a mess if you say "Yes"
> to every idea and you have to draw the line somewhere.
> * Add `__missing__` to `dict`. It might be a simple pass-through
> method for raising `KeyError`, but hey, maybe it'll simplify a
> code-path or two.
> <https://hg.python.org/cpython/file/tip/Objects/dictobject.c#l1723>
> * Add `__missing__` support to `collections.abc.Mapping`
> <https://hg.python.org/cpython/file/tip/Lib/_collections_abc.py#l595> (or
> I guess UserDict, but I'd be just as happy if that one went away
> completely :-). I'm sure I haven't thought through all the
> pitfalls, but (additional documentation aside) it seems like it
> could be as easy as:
>
>
>
> class Mapping(Sized, Iterable, Container):
> def __missing__(self, key):
> raise KeyError
>
> @abc.abstractmethod
> def __getitem__(self, key):
> self.__missing__(key)
>
> ...
I will admit I don't understand the push-back against adding
__missing__, and I'm mystified about the comment that users shouldn't be
subclassing dict. I thought one of the key advances late in the 2.x
series was easy(er) subclassing of the builtins.
Unless it's a practicality thing, what with dict being written in such a
subclass-hostile way (for performance reasions?):
class ADict(dict):
def __init__(self):
super(ADict, self).__init__()
self.names = []
def __delitem__(self, name):
if name in self.names:
self.names.remove(name)
super(ADict, self).__delitem__(name)
def __setitem__(self, name, value):
if name not in self.names:
self.names.append(name)
super(ADict, self).__setitem__(name, value)
my_dict = ADict()
my_dict['howdy'] = 'bye'
my_dict.update({'hola': 'adios'})
print(my_dict.names) # ['howdy']
print(my_dict.items()) # dict_items([('howdy','bye'), ('hola','adios')])
my_dict.pop('howdy')
del my_dict['hola']
print(my_dict.names) # ['howdy']
print(my_dict.items()) # dict_items([])
--
~Ethan~
More information about the Python-ideas
mailing list