I have a custom Sequence type. It is essentially a wrapper for a list plus a boolean flag and I wanted it to emulate usual immutable sequence behavior.
My issue is with slicing. I understand that in Python 3 the way to implement it is to have a __getitem__(key)
method that returns an item if %key
is a single index and a sliced sequence if %key
is a slice object. But how should I discriminate these cases?
I basically have two hypotheses.
sliced_list = self.wrapped_list[key]
if isinstance(key, slice):
return MyCustomSequenceType(sliced_list, boolean_flag)
return sliced_list
But this is evil, isn't it? Or
sliced_list = self.wrapped_list[key]
try:
return MyCustomSequenceType(sliced_list, boolean_flag)
except TypeError:
return sliced_list
The latter looks more pythonic. It relies on the fact that MyCustomSequenceType.__init__(self, datas, flag)
calls len(datas), it so raise TypeError
if %datas
is an integer
. But then, if __init__
raises TypeError
for another random issue it will be untraceable. Also http://wiki.cython.org/enhancements/numpy/getitem hints that isinstance
is faster (in fact more easily optimizable).
What should I do, then?
You could have a look through the standard library and copy what is done there. For example, calendar.py has:
def __getitem__(self, i):
funcs = self._months[i]
if isinstance(i, slice):
return [f(self.format) for f in funcs]
else:
return funcs(self.format)
which shows both explicit checking with isinstance
and partially ducking the issue by simply passing the index or slice through to the underlying list.