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
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to