[Python-Dev] Slicing
David Abrahams
David Abrahams" <david.abrahams@rcn.com
Wed, 19 Jun 2002 07:57:22 -0400
----- Original Message -----
From: "Michael Hudson" <mwh@python.net>
> > This seems to indicate that I can't, in general, pass a slice object to
> > PyObject_GetItem in order to do slicing.** Correct?
>
> No. The time machine has got you here; update to CVS and try again.
While that result is of interest, I think I need to support 2.2.1, so maybe
it doesn't make too much difference what the current CVS is doing.
> This comes down to the (slightly odd, IMHO) distinction between
> sequences and mappings, which doesn't really appear at the Python
> level.
>
> type_pointer->tp_as_sequence->sq_item
>
> takes a single int as a parameter
>
> type_pointer->tp_as_mapping->mp_subscr
>
> takes a PyObject*.
I know about those details, but of course they aren't really a cause: as
the current CVS shows, it *can* be handled.
> Builtin sequences (as of last week) have mp_subscr
> methods that handle slices. I haven't checked, but would be amazed if
> PyObject_GetItem can't now be used with sliceobjects.
Good to know.
> > So Python is doing some dispatching internally based on the types of
the
> > >>> class subint(int): pass
> > ...
> > >>> subint()
> > 0
> > >>> Z[subint():5]
> > Traceback (most recent call last):
> > File "<stdin>", line 1, in ?
> > TypeError: unsubscriptable object
>
> This last one is easy: you're trying to subscript the class object!
Oops, nice catch!
>>> Z()[subint():5]
getslice 0 5
> > 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?
>
> You can't do this logic from Python, AFAIK.
Why do you say that? Are you saying I should be looking at slots and not
attributes, plus special handling for classic classes (ick)?
> I think PyObject_GetItem is your best bet.
Well, not if I care about versions < 2.2.2. So, I'm modifying my logic
slightly:
def getslice(x,start,finish):
if (isinstance(start,int) and isinstance(finish,int)
and hasattr(type(x), '__getslice__')):
return x.__getslice__(start, finish)
else:
return x.__getitem__(slice(start,finish))
-Dave