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