Reputation: 40963
Some libraries like numpy, pandas or even python lists implement fancy indexing for its objects. This means I can do things like:
obj[1:3, :]
If I want to offer this functionality in my class I could try to overload the __getitem__
and the __setitem__
methods:
class Example(object):
def __getitem__(self, x):
pass
but I don't see how this could work as 1:3
is not a valid variable name. How can this functionality be achieved?
Upvotes: 6
Views: 835
Reputation: 298166
The only thing special about the slice notation is the shorthand for slice
, which makes your code equivalent to:
obj[(slice(1, 3), slice(None, None))]
The parameter passed to __getitem__
is the "index" of the item, which can be any object:
def __getitem__(self, index):
if isinstance(index, tuple):
# foo[1:2, 3:4]
elif isinstance(index, slice)
# foo[1:2]
else:
# foo[1]
Upvotes: 5
Reputation: 129011
Slices like 1:3
are turned into slice
objects and passed to your function. If you have multiple indexers, they are turned into a tuple
. To demonstrate:
>>> class Example(object):
... def __getitem__(self, index):
... return index
...
>>> example = Example()
>>> example['hello']
'hello'
>>> example[1:5]
slice(1, 5, None)
>>> example[1:5, 10:15]
(slice(1, 5, None), slice(10, 15, None))
Upvotes: 7