I have a class that subclasses the list object. Now I need to handle slicing. From everything I read on the intertubes this has to be done using the __getitem__
method. At least in Python 2.7+ which is what I'm using. I have done this (see below), but the __getitem__
method isn't called when I pass in a slice. Instead, a slice is done and a list is returned. I would like a new instance of myList returned.
Please help me discover what is wrong.
Thanks!
class myList(list):
def __init__(self, items):
super(myList, self).__init__(items)
self.name = 'myList'
def __getitem__(self, index):
print("__getitem__")
if isinstance(index, slice):
print("slice")
return self.__class__(
self[x] for x in range(*index.indices(len(self)))
)
else: return super(myList, self).__getitem__(index)
if __name__ == "__main__":
print("\nI'm tesing out custom slicing.\n")
N = 10
L = myList(range(N))
L3 = L[3]
L02 = L[:2]
See this note:
object.__getslice__(self, i, j)
Deprecated since version 2.0: Support slice objects as parameters to the
__getitem__()
method. (However, built-in types in CPython currently still implement__getslice__()
. Therefore, you have to override it in derived classes when implementing slicing.
So, because you subclass list
you have to overwrite __getslice__
, even though it's deprecated.
I think you should generally avoid subclassing builtins, there are too many weird details. If you just want a class that behaves like a list, there is a ABC to help with that:
from collections import Sequence
class MyList(Sequence):
def __init__(self, *items):
self.data = list(items)
def __len__(self):
return len(self.data)
def __getitem__(self, slice):
return self.data[slice]
s = MyList(1,2,3)
# lots of free methods
print s[1:2], len(s), bool(s), s.count(3), s.index(2), iter(s)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With