[Python-Dev] Slicing
David Abrahams
David Abrahams" <david.abrahams@rcn.com
Tue, 18 Jun 2002 14:21:23 -0400
I did a little experiment to see if I could use a uniform interface for
slicing (from C++):
>>> range(10)[slice(3,5)]
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: sequence index must be integer
>>> class Y(object):
... def __getslice__(self, a, b):
... print "getslice",a,b
...
>>> y = Y()
>>> y[slice(3,5)]
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: unsubscriptable object
>>> y[3:5]
getslice 3 5
This seems to indicate that I can't, in general, pass a slice object to
PyObject_GetItem in order to do slicing.** Correct?
So I went looking around for alternatives to PyObject_GetItem. I found
PySequence_GetSlice, but that takes int parameters, and AFAIK there's no
rule saying you can't slice on strings, for example.
Further experiments revealed:
>>> y['hi':'there']
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: unsubscriptable object
>>> class X(object):
... def __getitem__(self, x):
... print 'getitem',x
...
>>> X()['hi':'there']
getitem slice('hi', 'there', None)
So I /can/ slice on strings, but only through __getitem__(). And...
>>> class Z(Y):
... def __getitem__(self, x):
... print 'getitem',x
...
>>> Z()[3:5]
getslice 3 5
>>> Z()['3':5]
getitem slice('3', 5, None)
So Python is doing some dispatching internally based on the types of the
slice elements, but:
>>> class subint(int): pass
...
>>> subint()
0
>>> Z[subint():5]
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: unsubscriptable object
So it's looking at the concrete type of the slice elements. I'm not sure I
actually understand how this one fails.
I want to make a generalized getslice function in C which can operate on a
triple of arbitrary objects. Here's the python version I came up with:
def getslice(x,start,finish):
if (type(start) is type(finish) is int
and hasattr(type(x), '__getslice__')):
return x.__getslice__(start, finish)
else:
return x.__getitem__(slice(start,finish))
Have I got the logic right here?
Thanks,
Dave
**it seems like a good idea to make it work in the Python core, by
recognizing slice objects and dispatching the elements to __getslice__ if
they are ints and if one is defined. Have I overlooked something?
+---------------------------------------------------------------+
David Abrahams
C++ Booster (http://www.boost.org) O__ ==
Pythonista (http://www.python.org) c/ /'_ ==
resume: http://users.rcn.com/abrahams/resume.html (*) \(*) ==
email: david.abrahams@rcn.com
+---------------------------------------------------------------+