What method does slice notation call?

Alex Martelli aleax at aleax.it
Thu Oct 9 08:10:12 EDT 2003


Robert Brewer wrote:

>>>> class A(types.DictType):
> ...   def __getitem__(self, key):
> ...           return types.DictType.__getitem__(self, key)
> ...
>>>> a = A()
>>>> a[0] = 3
>>>> a.__getitem__ = lambda x: "w00t"
>>>> a.__getitem__(0)
> 'w00t'
>>>> a
> {0: 3}
>>>> a[0]
> 3
> 
> Can anyone tell me why a[0] doesn't return "w00t", like I thought it
> would? What method is a[0] calling? Is there a way to override it?

For all except "classic classes" (which have to do lots of hacking
behind the scenes for backwards compatibility, sigh), a[0] means
roughly the equivalent of:

    getattr(type(a), '__getitem__')(a, 0)

so, if you want to have a[0] invoke something different, you must
change type(a) accordingly, e.g.:

def changeindexing(a, newgetitem):
    class x(type(a)):
        __getitem__ = newgetitem
    a.__class__ = x

so, for example:

def changeindexing(a, newgetitem):
    class x(type(a)):
        __getitem__ = newgetitem
    a.__class__ = x

class A(dict):
        def __getitem__(self, key):
                return dict.__getitem__(self, key)

a = A()
a[0] = 3
a.__getitem__ = lambda x: "w00t"
print a.__getitem__(0)
print a
print a[0]

changeindexing(a, lambda self, x: 'blaap')

print a.__getitem__(0)
print a
print a[0]

prints:

w00t
{0: 3}
3
w00t
{0: 3}
blaap


Note that the function you pass to changeindexing does need a 'self', just
like any other method.  If you don't want that, you can use a staticmethod,
of course (but then the function won't have access to the specific instance
it's being called on).


Alex





More information about the Python-list mailing list