overriding __getitem__ for a subclass of dict

Steve Howell showell30 at yahoo.com
Tue Nov 17 06:17:48 CET 2009


On Nov 16, 4:06 pm, greg <g... at cosc.canterbury.ac.nz> wrote:
> Christian Heimes wrote:
> > 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.
>
> There's also a semantic problem. Since new-style
> classes are also instances (of class 'type') and you
> can create subclasses of 'type', if special methods
> were looked up on instances, it would be ambiguous
> whether an attribute '__getitem__' on a class was
> meant to specify the behaviour of the [] operation
> on its instances, or on the class itself.
>
> This problem didn't arise with old-style classes,
> because classes and instances were clearly separated
> (i.e. old-style classes were not old-style instances).

That explanation makes some sense to me.  Given the ambiguity and the
backward compatibility issues, I would argue that both of the
commented lines in the program below should fail hard with a useful
warning.  Only one of them actually does.  The other just silently no-
ops.

    class A(dict):
        pass

    a = A()
    a['ignore'] = 'x'
    a.__getitem__ = lambda key: 'foo' # exercise in futility

    b = dict()
    b['ignore'] = 'x'
    b.__getitem__ = lambda key: 'foo' # hard failure

Tested under 2.6.

It seems like if __getitem__ is truly a special method, it should get
special treatment whenever you try to use it, even if that special
treatment is just an explicit error message that its use makes no
sense in a particular context.  If you allow __getitem__ to exist on
a, then you create situations where __getitem__ is basically an
instance method on an instance of a subtype of dict, which sounds
awfully ambiguous to me, given that the whole intent of __getitem__ is
to define the behavior of [] on classes.










More information about the Python-list mailing list