overriding __getitem__ for a subclass of dict

Steve Howell showell30 at yahoo.com
Sun Nov 15 20:35:53 EST 2009


On Nov 15, 4:58 pm, Steve Howell <showel... at yahoo.com> wrote:
> On Nov 15, 4:03 pm, Christian Heimes <li... at cheimes.de> wrote:
>
> > Try this untested code:
>
> > class Spam(dict):
> >     def __getitem__(self, key):
> >         getitem = self.__dict__.get("__getitem__", dict.__getitem__)
> >         return getitem(self, key)
> > [...]
>
> [I originally responded...] Not sure how this helps me, unless I am misunderstanding...
>

Ok, now I get where you were going with the idea.  The following code
runs as expected.  Even in pure testing mode, I would want to make it
a little more robust, but it illustrates the basic idea that you can
monitor just particular objects by overriding the class method to look
for an attribute on the instance before doing any special processing.

    class MyDict(dict):
        pass

    dict1 = MyDict()
    dict1['foo'] = 'bar'

    dict2 = MyDict()
    dict2['spam'] = 'eggs'

    dict3 = MyDict()
    dict3['BDFL'] = 'GvR'

    def spy(dict):
        def mygetitem(self, key):
            if hasattr(self, '__SPYING__'):
                value = self.__class__.__old_getitem__(self, key)
                print 'derefing %s to %s on %s' % (key, value, self)
                return value
        if not hasattr(dict.__class__, '__HOOKED__'):
            setattr(dict.__class__, '__old_getitem__',
dict.__class__.__getitem__)
            setattr(dict.__class__, '__getitem__', mygetitem)
            setattr(dict.__class__, '__HOOKED__', True)
        dict.__SPYING__ = True

    dict1['foo'] # not spied yet
    spy(dict1) # this changes class and instance
    dict1['foo'] # spied
    dict2['spam'] # not spied
    spy(dict3) # this only changes instance
    dict3['BDFL'] # spied
    dict2['spam'] # spied

Thanks, Christian!




More information about the Python-list mailing list