From: Ethan Furman on 3 Aug 2010 21:09 Christian Heimes wrote: >> Perhaps punctuation will help clarify my intent: >> >> __missing__ is *not* part of (dict)s, as shown by dir(dict()): > > Indeed, that's correct. Can we agree, that __missing__ is an optional > feature of the dict interface, that can be implemented in subclasses of > dict? Absolutely. ~Ethan~
From: John Posner on 3 Aug 2010 22:49 On 8/3/2010 6:48 PM, Ethan Furman wrote: > Christian Heimes wrote: >>> I just went and read the entry that had the bogus claim -- >>> personally, I didn't see any confusion. I would like to point out the >>> __missing__ is *not* part of dicts (tested on 2.5 and 2.6 -- don't >>> have 2.7 installed yet). >> >> I beg your pardon but you are wrong. __missing__ is available for all >> *subclasses* of dict since Python 2.5. See >> http://svn.python.org/view/python/branches/release25-maint/Objects/dictobject.c?revision=81031&view=markup >> >> >>>>> class mydict(dict): >> ... def __missing__(self, key): >> ... print "__missing__", key >> ... raise KeyError(key) >> ... >>>>> m = mydict() >>>>> m[1] >> __missing__ 1 >> Traceback (most recent call last): >> File "<stdin>", line 1, in <module> >> File "<stdin>", line 4, in __missing__ >> KeyError: 1 > > Perhaps punctuation will help clarify my intent: > > __missing__ is *not* part of (dict)s, as shown by dir(dict()): > > ['__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__', > '__doc__', '__eq__', '__ge__', '__getattribute__', '__getitem__', > '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', > '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', > '__repr__', '__setattr__', '__setitem__', '__str__', 'clear', 'copy', > 'fromkeys', 'get', 'has_key', 'items', 'iteritems', 'iterkeys', > 'itervalues', 'keys', 'pop', 'popitem', 'setdefault', 'update', > 'values'] > > And, just to state what is hopefully obvious, if you don't create > __missing__ yourself, it still isn't in the subclass: Right, a __missing__ method does not magically appear in the subclass. Rather, the subclass is allowed (but not required) to define a method named __missing__, which will "magically" be called in certain situations. Here's a dict subclass that uses the "magic" for a purpose that has nothing to do with default values: class BadKeyTrackerDict(dict): def __init__(self, *args, **kwargs): dict.__init__(self, *args, **kwargs) self.bad_keys = set([]) def __missing__(self, key): """ add missing key to "bad keys" set """ self.bad_keys.add(key) raise KeyError Note that "defaultdict" is nowhere in sight here. It's the dict class (or type) itself that provides the magic -- but only for its subclasses. > > --> class somedict(dict): > ... "Is __missing__ defined if I don't define it? Nope." > ... > --> sd = somedict() > --> sd[1] > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > KeyError: 1 > --> dir(sd) > ['__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__', > '__dict__', '__doc__', '__eq__', '__ge__', '__getattribute__', > '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', > '__len__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', > '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__str__', > '__weakref__', 'clear', 'copy', 'fromkeys', 'get', 'has_key', 'items', > 'iteritems', 'iterkeys', 'itervalues', 'keys', 'pop', 'popitem', > 'setdefault', 'update', 'values'] > > ~Ethan~ -John
From: John Posner on 6 Aug 2010 16:07 On 8/2/2010 11:00 PM, John Posner wrote: > On 7/31/2010 1:31 PM, John Posner wrote: >> >> Caveat -- there's another description of defaultdict here: >> >> http://docs.python.org/library/collections.html#collections.defaultdict >> >> ... and it's bogus. This other description claims that __missing__ is a >> method of defaultdict, not of dict. > > Following is a possible replacement for the bogus description. Comments > welcome. I intend to submit a Python doc bug, and I'd like to have a > clean alternative to propose. After some off-list discussion with Ethan Furman (many thanks!), the Python Doc bug is submitted: #9536 at bugs.python.org. -John
From: Wolfram Hinderer on 6 Aug 2010 18:24 On 6 Aug., 22:07, John Posner <jjpos...(a)optimum.net> wrote: > On 8/2/2010 11:00 PM, John Posner wrote: > > > On 7/31/2010 1:31 PM, John Posner wrote: > > >> Caveat -- there's another description of defaultdict here: > > >>http://docs.python.org/library/collections.html#collections.defaultdict > > >> ... and it's bogus. This other description claims that __missing__ is a > >> method of defaultdict, not of dict. > > > Following is a possible replacement for the bogus description. Comments > > welcome. I intend to submit a Python doc bug, and I'd like to have a > > clean alternative to propose. > > After some off-list discussion with Ethan Furman (many thanks!), the > Python Doc bug is submitted: #9536 at bugs.python.org. > > -John This is probably nitpicking, but the patch calls __missing__ a special method. However, unlike special methods, it is not invoked by "special syntax" but by the dict's __getitem__ method. (len() invokes __len__ on any object - you can't do something similar with __missing__.) __missing__ is also not listed as a special method on http://docs.python.org/py3k/reference/datamodel.html#special-method-names However, "normal" special method lookup seems to be used.
From: John Posner on 6 Aug 2010 19:29
On 8/6/2010 6:24 PM, Wolfram Hinderer wrote: > > This is probably nitpicking, but the patch calls __missing__ a special > method. However, unlike special methods, it is not invoked by "special > syntax" but by the dict's __getitem__ method. (len() invokes __len__ > on any object - you can't do something similar with __missing__.) > > __missing__ is also not listed as a special method on > http://docs.python.org/py3k/reference/datamodel.html#special-method-names > > However, "normal" special method lookup seems to be used. Fair enough. Please add your comment to #9536 at bugs.python.org. Tx, John |