[Tutor] __getslice__

Michael P. Reilly arcege@shore.net
Fri, 17 Nov 2000 10:30:26 -0500 (EST)


> Hi.
> I read in the official Python Reference Manual that in Python 2.0 the
> __getslice__  and related methods are deprecated, and that one should
> instead use the __getitem__ and related methods. I've been giving it a
> try, but I don't seem to be able to get a slice of an user defined
> sequence object, using the __getitem__ method, and I can't find any help
> in the docs (or else I find it but i don't get it, sorry)...
> Can anybody help?
> tia,
> Ze amoreira
> amoreira@mercury.ubi.pt

Hi there.  I don't feel that they really documented this well in the
release notes for 2.0, so I can see where there is some confusion.

The new "preferred" idiom is to only have a __getitem__ (and the like)
method.  Previously, there was partial support in the __[dgs]etitem__
methods,  mostly to handle the Ellipsis object ("..."), but it would
handle the Slice type (which was in there in 1.5.2).

Python 1.5.2 (#2, May 11 1999, 17:14:37)  [GCC 2.7.2.1] on freebsd3
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> class A:
...   def __getitem__(self, index):
...     print type(index), repr(index), str(index)
...
>>> a = A()
>>> a[...]
<type 'ellipsis'> Ellipsis Ellipsis
>>> a[1]
<type 'int'> 1 1

Try to give a regular subscript or the special ellipses ('...'), and
the getitem/setitem/delitem methods are used.  But...

>>> a[:]
Traceback (innermost last):
  File "<stdin>", line 1, in ?
AttributeError: __getslice__
>>> slice
<built-in function slice>
>>> slice(0, 3, 4)
slice(0, 3, 4)
>>> type(slice(0, 3, 4))
<type 'slice'>
>>> s = slice(0, 100, 4)
>>> s
slice(0, 100, 4)
>>> s.start
0
>>> s.stop
100
>>> s.step
4
>>> a[s]
<type 'slice'> slice(0, 100, 4) slice(0, 100, 4)
>>>

Slice objects were used in Python 1.5.2; part of the language allowed
for the step to be specified.

>>> a[::2]
<type 'slice'> slice(None, None, 2) slice(None, None, 2)
>>>

In Python 2.0, this slice object is now given to the __getitem__,
__setitem__ and __delitem__ methods even when there is not step given.

Python 2.0 (#7, Nov 14 2000, 11:06:28)
[GCC 2.7.2.1] on freebsd3
Type "copyright", "credits" or "license" for more information.
>>> import sys
>>> class A:
...   def __getitem__(self, index):
...     print type(index), repr(index), str(index)
...
>>> a = A()
>>> a[1]
<type 'int'> 1 1
>>> a[...]
<type 'ellipsis'> Ellipsis Ellipsis
>>>
>>> a[:]
<type 'slice'> slice(0, 2147483647, None) slice(0, 2147483647, None)
>>> sys.maxint
2147483647
>>>

But when you and a __getslice__ method, things change back to how they
worked in Python 1.x:

>>> def getslice(self, lo, hi):
...   print (type(lo), repr(lo), str(lo)), (type(hi), repr(hi), str(hi))
...
>>> A.__getslice__ = getslice
>>> a[:]
(<type 'int'>, '0', '0') (<type 'int'>, '2147483647', '2147483647')
>>>

This means that as long as there is a __getslice__ method in the class,
the system will use that instead of __getitem__.

I hope this helps you figure out what you need.

  -Arcege

References:
Python Reference Manual, section 3.3.4 Emulating sequence and mapping types
  <URL: http://www.python.org/doc/current/ref/sequence-types.html>
Python Reference Manual, section 5.3.3 Slicings
  <URL: http://www.python.org/doc/current/ref/slicings.html>

-- 
------------------------------------------------------------------------
| Michael P. Reilly, Release Manager  | Email: arcege@shore.net        |
| Salem, Mass. USA  01970             |                                |
------------------------------------------------------------------------