Slice objects. How to apply them to strings?

Bengt Richter bokr at oz.net
Fri Mar 29 20:03:46 EST 2002


On Fri, 29 Mar 2002 19:29:25 +0000, Dale Strickland-Clark <dale at riverhall.NOTHANKS.co.uk> wrote:

>Dale Strickland-Clark <dale at riverhall.NOTHANKS.co.uk> wrote:
>
>>I'm using Python 2.1 here but this still seems to apply on 2.2
>>
>>I have a little string-based class which needs to emulate strings for
>>most things. This includes slicing.
>>
>>So I need a __getitem__ magic method. 
>>
>>This will get passed a slice object.
>>
>>How am I supposed to translate this into a string slice? 
>>
>>This seems to be the tidiest I can come up with and it's a mess:
>>
>>def __getitem__(self, item):
>>    if item.step:
>>        return self.s[item.start: item.stop: item.step]
>>    if item.start:
>>        return self.s[item.start: item.stop]
>>    return self.s[item.stop]
>>
>>If 'item' is a slice object, shouldn't I just be able to say:
>>
>>    self.s[item]
>>?
>>
>>Wouldn't this be really sensible?
>>
>>What's worse, is that I can't even do this:
>>
>>import operator
>>operator.getitem(self.s, item)
>>
>>Somebody please tell me I'm being dim and I've missed something. How
>>do you apply a slice object to a sequence?
>>
>>Thanks
>
>Can anyone shed any light on this for me?
>

Why not subclass str? Here is a toy:

 >>> class SX(str):
 ...     def __getitem__(self,item):
 ...         if type(item) is int: return 'SX<'+str.__getitem__(self,item)+'>'
 ...         return 'SX<:<'+''.join(
 ...             [str(self)[i] for i in xrange(item.start,item.stop,item.step)]
 ...         )+'>:>'
 ...     def __getslice__(self,i,j):
 ...         return 'SX<<'+str.__getslice__(self,i,j)+'>>'
 ...
 >>> s=SX('0123456789')
 >>> s
 '0123456789'
 >>> s[1]
 'SX<1>'
 >>> s[1:8]
 'SX<<1234567>>'
 >>> s[1:8:2]
 'SX<:<1357>:>'


However, to be robust, I guess one must watch for slices and tuples
in __getitem__ to cover all the variety, and perhaps expect just
straight start,stop in __getslice__ ? (Can someone verify the latter?)

 >>> class C:
 ...     def __init__(self,*v): print 'init',v
 ...     def __getitem__(self,*i): print 'getitem',i
 ...     def __getslice__(self,*slc): print 'getslice',slc
 ...
 >>> c=C('012345')
 init ('012345',)
 >>> c[1]
 getitem (1,)
 >>> c[1,2]
 getitem ((1, 2),)
 >>> c[1:2]
 getslice (1, 2)
 >>> c[1,2,3]
 getitem ((1, 2, 3),)
 >>> c[1:2:3]
 getitem (slice(1, 2, 3),)
 >>> c[1:2,3:4]
 getitem ((slice(1, 2, None), slice(3, 4, None)),)
 >>> c[1:]
 getslice (1, 2147483647)
 >>> c[:2]
 getslice (0, 2)
 >>> c[:2,3]
 getitem ((slice(None, 2, None), 3),)
 >>> c[:2,3:]
 getitem ((slice(None, 2, None), slice(3, None, None)),)

Regards,
Bengt Richter



More information about the Python-list mailing list