473,573 Members | 2,259 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Rationale behind the deprecation of __getslice__?

Hi all,

I was wondering if someone can help me understand why __getslice__ has been
deprecated, yet it remains necessary to implement it for simple slices (i:j),
while __getitem__ gets called for extended slices (i:j:k).

The problem with this approach, besides a bit of code duplication, is that
classes which implement slicing must now do runtime type-checking inside
__getitem__. Here's a trivial example:
############### ############### ############### ############### ####
import types

class Vector(list):
def __init__(self,a rg,wrap=0):
'''
If arg is an integer, make a new zero vector of length n.
Otherwise, arg must be a python sequence or another vector,
and a new (deep) copy is generated.
'''
if isinstance(arg, int):
list.__init__(s elf,[0.0]*arg)
else:
list.__init__(s elf,arg)

def __getitem__(sel f,key):
"""called for single-element OR slice access"""
if type(key) is types.SliceType :
return Vector(list.__g etitem__(self,k ey))
else:
return list.__getitem_ _(self,key)

def __getslice__(se lf,i,j):
"""Deprecat ed since 2.0, but still called for non-extended slices.

Since extended slices are handled by __getitem__, I'm just deferring
to that one so all actual implementation is done there. Why this is
not the default (since they deprecated __getslice__) is beyond me."""

return self.__getitem_ _(slice(i,j))

print 'a is a vector'
a = Vector(5)
print a
print type(a)
print

print 'b is a slice of a'
b = a[1:3]
print b
print type(b)
print

print 'c is an element of a'
c = a[1]
print c
print type(c)

############### ############### ############### ############### ####

What bugs me is that typecheck for slicing which seems to be necessary inside
of the __getitem__ method. I have the feeling that the code would be much
cleaner if I could simply use __getslice__ for slices and __getitem__ for
items, and that bundling the two in this hybrid mode is reall ugly and
unpythonic. Am I just missing something?

Thanks for any help,

f

Jul 18 '05 #1
18 2726
Fernando Perez wrote:
I was wondering if someone can help me understand why __getslice__ has been
deprecated, yet it remains necessary to implement it for simple slices (i:j),
while __getitem__ gets called for extended slices (i:j:k).


I don't think this is true -- everything goes to __getitem__:
class C(object): .... def __getitem__(sel f, *args, **kwds):
.... print args, kwds
.... c = C()
c[1] (1,) {} c[1:2] (slice(1, 2, None),) {} c[1:2:-1] (slice(1, 2, -1),) {}

All you have to do is check the type of the single argument to __getitem__:
class C(object): .... def __getitem__(sel f, x):
.... if isinstance(x, slice):
.... return x.indices(10)
.... else:
.... return x
.... c = C()
c[1] 1 c[1:2] (1, 2, 1) c[1:2:-1]

(1, 2, -1)

Steve
Jul 18 '05 #2
Fernando Perez wrote:
classes which implement slicing must now do runtime type-checking inside
__getitem__.


Just in case you thought that they wouldn't have to do runtime
type-checking otherwise:
class C(object): .... def __getitem__(sel f, x):
.... print type(x), x
.... c = C()
c[1] <type 'int'> 1 c[1:2] <type 'slice'> slice(1, 2, None) c[1:2:-1] <type 'slice'> slice(1, 2, -1) c[1,2] <type 'tuple'> (1, 2) c[1,2:3] <type 'tuple'> (1, slice(2, 3, None)) c['1'] <type 'str'> 1 c[[]]

<type 'list'> []

You can put just about anything in a __getitem__ call. Do you really
want a method for each of the variants above?

Steve
Jul 18 '05 #3
Steven Bethard wrote:
Fernando Perez wrote:
I was wondering if someone can help me understand why __getslice__ has been
deprecated, yet it remains necessary to implement it for simple slices
(i:j), while __getitem__ gets called for extended slices (i:j:k).


I don't think this is true -- everything goes to __getitem__:
>>> class C(object): ... def __getitem__(sel f, *args, **kwds):
... print args, kwds
... >>> c = C()
>>> c[1] (1,) {} >>> c[1:2] (slice(1, 2, None),) {} >>> c[1:2:-1]

(slice(1, 2, -1),) {}


Not if you subclass builtin types like list:

In [6]: class mylist(list):
...: def __getitem__(sel f,*args,**kwds) :
...: print 'mylist getitem'
...: print args,kwds
...:

In [7]: a=mylist()

In [8]: a[1]
mylist getitem
(1,) {}

In [9]: a[1:2]
Out[9]: []

In [10]: a[1:2:3]
mylist getitem
(slice(1, 2, 3),) {}

I did this testing, which is what forced me to implement __getslice__
separately in my little example, to satisfy calls with simple i:j slices.

Best,

f

Jul 18 '05 #4
Steven Bethard wrote:
Fernando Perez wrote:
classes which implement slicing must now do runtime type-checking inside
__getitem__.
Just in case you thought that they wouldn't have to do runtime
type-checking otherwise:
>>> class C(object):

... def __getitem__(sel f, x):
... print type(x), x
...


[...]
You can put just about anything in a __getitem__ call. Do you really
want a method for each of the variants above?


I guess that conceptually it just felt natural to me to keep separate methods
for dealing with a slice (get many elements out) and other types of indexing,
which I tend to think of as 'scalar' indexing.

Regards,

f

Jul 18 '05 #5
Fernando Perez wrote:
I was wondering if someone can help me understand why __getslice__ has been deprecated, yet it remains necessary to implement it for simple slices (i:j), while __getitem__ gets called for extended slices (i:j:k).

The problem with this approach, besides a bit of code duplication, is that classes which implement slicing must now do runtime type-checking inside __getitem__.


I'm pretty sure it's to support multidimensiona l array slicing.
Consider an array reference such as a[1,2:5,4,6:9,10:]. Now what do
you do? You have mixed slices and indices. The
__getslice__/__getitem__ paradigm isn't versatile enough to handle this
situation. In that light, I'd say checking for slices is the lesser
evil.

As for why list objects still use getslice--they probably shouldn't.
I'd file a bug report.
--
CARL BANKS

Jul 18 '05 #6
Fernando Perez wrote:
Steven Bethard wrote:
Fernando Perez wrote:
I was wondering if someone can help me understand why __getslice__ has been
deprecated , yet it remains necessary to implement it for simple slices
(i:j), while __getitem__ gets called for extended slices (i:j:k).
I don't think this is true -- everything goes to __getitem__:
[snip]
Not if you subclass builtin types like list:


Ahh, I didn't catch that your problem was with list. Yeah, so if a
__getslice__ exists, this is used first. Unfortunately, by inheriting
from list, you inherit __getslice__ from list. Another example without
builtin types:
class C(object): .... def __getitem__(sel f, x):
.... print "C:getitem"
.... def __getslice__(se lf, *args):
.... print "C:getslice "
.... class D(C): .... def __getitem__(sel f, x):
.... print "D:getitem"
.... d = D()
d[1] D:getitem d[1:2] C:getslice d[1:2:-1]

D:getitem

While the D class doesn't define __getslice__, it's parent class does,
so it has the same behavior you're running into. I don't see how to fix
this other than overriding __getslice__ to call __getitem__ like you have.

Unfortunately, I don't think __getslice__ can be removed from list (and
str and tuple) because of backwards compatibility constraints...

Steve
Jul 18 '05 #7
Steven Bethard wrote:
Unfortunately, I don't think __getslice__ can be removed from list (and str and tuple) because of backwards compatibility constraints...


Wouldn't it work to have __getslice__ call __getitem__? And, since
that would be too much of a performance hit, have it check whether its
type is list (or str or tuple), and only call __getitem__ if it is not
(i.e., only for subclasses). I don't think that would be too bad.

Subclasses would still be free to override __getslice__, but wouldn't
have to.
--
CARL BANKS

Jul 18 '05 #8
Fernando Perez wrote:
I guess that conceptually it just felt natural to me to keep separate methods
for dealing with a slice (get many elements out) and other types of indexing,
which I tend to think of as 'scalar' indexing.


Yeah, I can see that a bit.

Ignoring dicts for the moment (and concerning ourselves only with
"sequences" ), you're probably right in thinking that that slice objects
are the second most common thing to get in __getitem__ (second to ints
of course). But there is heavy use of other objects in various other
modules, most notably tuples in numarray:
import numarray as na
a = na.arange(24, shape=(2, 3, 4))
a array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],

[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]]) a[0,1,2] 6 a[0,1] array([4, 5, 6, 7]) a[...,3] array([[ 3, 7, 11],
[15, 19, 23]]) a[1,:,0]

array([12, 16, 20])

Presumably the numarray code has to do quite a bit of type checking to
perform all these slicings right (and I didn't even show you what
happens when you use another array as an "index"). I'm not necessarily
saying that all this type checking is a good thing, but because people
will always find new things that they want to index by, adding
__getxxx__ methods for each of the index types is probably not the right
road to go down...

Steve
Jul 18 '05 #9
Carl Banks wrote:
As for why list objects still use getslice--they probably shouldn't.
I'd file a bug report.


I'm not convinced this is actually a bug; it works just like the docs
promise:

------------------------------------------------------------
http://docs.python.org/ref/sequence-methods.html
__getslice__( self, i, j)
....
Called to implement evaluation of self[i:j].
....
If no __getslice__() is found, a slice object is created instead, and
passed to __getitem__() instead.
....
For slice operations involving extended slice notation, or in absence of
the slice methods, __getitem__(), __setitem__() or __delitem__() is
called with a slice object as argument.
------------------------------------------------------------

So the docs imply that if __getslice__ exists, it will be used before
trying __getitem__. Since list defines __getslice__, list.__getslice __
will be used before __getitem__ in any class that inherits from list.

This is certainly a wart though. I'd love to see list.__getslice __
removed, leaving only list.__getitem_ _, but I suspect that this kind of
backwards-incompatible change would be frowned on...

Guess we could file a feature request?

Steve
Jul 18 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

24
2298
by: Matt Feinstein | last post by:
Hi all-- I'm new to Python, and was somewhat taken aback to discover that the core language lacks some basic numerical types (e.g., single-precision float, short integers). I realize that there are extensions that add these types-- But what's the rationale for leaving them out? Have I wandered into a zone in the space/time continuum where...
1
2417
by: Dave Huang | last post by:
Hi, I don't actually know Python; I'm just trying to debug a problem I encounted in another program, so apologies if this has been covered before. I did do some Google searches though, and didn't find anything that specifically addressed this :) According to the documentation at <http://docs.python.org/ref/sequence-methods.html>,...
0
1398
by: Alexander Grigoriev | last post by:
I hope Mr. Stroustrup can give an answer to this question: What was rationale behind the requirements to use an ampersand and a fully qualified name of a function, to form a pointer to a member function? Is there any syntax ambiguity without those? MS C++ compiler is quite happy when a plain function name is used (I haven't tried it in ANSI...
2
2766
by: Howard Jess | last post by:
Given the html at the end of this message, I see how a DOM NodeList exhibits its "live" behavior; that is, adding elements to a document can change any NodeList variables, when there's *no* code that refers to them. I suppose I can imagine cases where this idea would be useful, but I can imagine many more where I'd like to get a *static*...
21
4579
by: Andreas Huber | last post by:
Hi there Spending half an hour searching through the archive I haven't found a rationale for the following behavior. using System; // note the missing Flags attribute enum Color {
1
1250
by: Kay Schluehr | last post by:
In almost any case I install a Python package via distutils some directories in the package tree are left behind e.g. the docs, licenses, tests etc. I wonder if there is some rationale behind this? Should it be left to the "creative freedom" of the user to copy the docs whereever she wants or is there a dedicated place for them and if any why...
35
2808
by: dragoncoder | last post by:
Just a simple theoritical question to the experts. What was the rationale behind making STL containers follow copy semantics rather than reference semantics. References almost always make things easier without much of overhead. Then why not reference ? Thanks /P
5
1941
by: Torsten Bronger | last post by:
Hallöchen! According to <http://docs.python.org/ref/sequence-methods.html>, __getslice__ is deprecated. At the moment, I derive an own class from unicode and want to implement my own slicing. I found that I have to override __getslice__ since __getitem__ isn't called when I have something like my_instance in my code. According to...
1
1421
by: Nick Bastin | last post by:
I've done some searching in this newsgroup and on the internet and haven't found an answer, so I thought I'd ask here... :-) I don't understand why full specialization of a member function template in a class template is only valid if you fully specialize the class template as well. Consider the following example: template<class T,...
0
7710
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
8039
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
1
7800
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
8092
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
6437
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
1
5606
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
5296
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
1
2230
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1332
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.