overriding __getitem__ for a subclass of dict

MRAB python at mrabarnett.plus.com
Mon Nov 16 01:24:19 CET 2009


Christian Heimes wrote:
> Steve Howell wrote:
>> Does anybody have any links that points to the rationale for ignoring
>> instance definitions of __getitem__ when new-style classes are
>> involved?  I assume it has something to do with performance or
>> protecting us from our own mistakes?
> 
> Most magic methods are implemented as descriptors. Descriptors only
> looked up on the type to increase the performance of the interpreter and
> to simply the C API. The same is true for other descriptors like
> properties. The interpreter invokes egg.__getitem__(arg) as
> type(egg).__getitem__(egg, arg).
> 
>> So now I am still in search of a way to hook into calls to foo[bar]
>> after foo has been instantiated.  It is all test code, so I am not
>> particularly concerned about safety or future compatibility.  I can do
>> something really gross like monkeypatch Foo class instead of foo
>> instance and keep track of the ids to decide when to override
>> behavior, but there must be a simpler way to do this.
> 
> Try this untested code:
> 
> class Spam(dict):
>     def __getitem__(self, key):
>         getitem = self.__dict__.get("__getitem__", dict.__getitem__)
>         return getitem(self, key)
> 
> Because dict is the most important and speed critical type in Python it
> has some special behaviors. If you are going to overwrite __getitem__ of
> a dict subclass then you have to overwrite all methods that call
> __getitem__, too. These are get, pop, update and setdefault.
> 
I wonder whether it's possible to define 2 behaviours, an optimised one
for instances of a class and another non-optimised one for instances of
a subclasses. That would make it easier to subclass built-in classes
without losing their speed.



More information about the Python-list mailing list