[MATRIX-SIG] Change slice object?
Janko Hauser
jhauser@ifm.uni-kiel.de
Mon, 24 Nov 1997 10:59:11 +0100 (CET)
Konrad Hinsen writes:
> > Also then there is no need for __getitem__ if one uses indexing. But I
> > think the method is needed for the for-loop construct, right?
>
> Right. And also for indexing with a single number, e.g. a[5].
>
My idea was that exactly this kind of indexing should also be done by
__getslice__, with the syntax slice(5,6,None). Currently one gets a
mix of two types of indexing (a[5,:,:] for example). But I don't know
the overhead of __getslice__ versus __getitem__
> > But in every function which deals with slicing, one can be shure to
> > get only a tuple of slice objects.
>
> True. Still it would break code that relies on the current interpretation.
> It would probably break my netCDF module, for example.
>
This is truly the bad side of such a change, so I will try to build a
class wich can simplify the handling of indices. First I make a
shadow-class for slice (see end of this mail) and than a
composer class wich handles the index argument of __get{slice,item}__.
> > I don't see, how big the impact of this change would be to the other
> > sequence objects in python.
>
> None at all, because only arrays use multidimensional indexing and
> slice objects!
>
That's good.
> > One other idea. What's the way to have a __cmp__ method for slice
> > objects to test if a slice is completly in another slice or
> > overlapping at both or only one end.
>
> That could easily be done, but what would it be good for?
I cache array slices from netcdf-files and want to see, if a new
request can be taken from the cached arrays or must be loaded from the
file.
Oh, by the way, I want to ask the more OO-knowing people if this is a
appropiate way to handle attribute access.
I have a class wich represents a region. I can slice the region and
the get variables in that region. I catch the request in __getattr__
and load or calculate the desired variable of that region. For the
user this looks like data-access, because she gets an arrayobject. Or
should something like this be implemented with special functions, to
make it clear, that there is something happening?
r[12,8,:,:] # slice the hole region, internally hold only the
# information of the currently activ region
r.temp # if not cached, load data for this region from file
r.vorticity # load u and v and calculate vorticity in this region
r[13,8,:,:] # next timestep ...
The temp and vorticity fields are actually UserArrays, so they know
more about themselves as normal arrays.
__Janko
################## > nslice.py < ##################################
"""
Provides a class for a little bit more handy slice object
called nslice.
1997 Janko Hauser jhauser@ifm.uni-kiel.de
"""
import Numeric
N=Numeric
def test():
"""
main()
Test the nslice class
"""
a = N.arange(12)
sl = slice(0,3,None)
n_sl = nslice(sl)
print 'TEST for same behavior'
print a[sl]
print a[n_sl()]
sl = slice(0,10,2)
n_sl.stop = 10
n_sl.step = 2
print a[sl]
print a[n_sl()]
print 'TEST for comparisson'
print n_sl, sl, cmp(n_sl,sl)
n_sl.stop = 11
print n_sl, sl, cmp(n_sl,sl)
n_sl.step = 3
n_sl.stop = 10
print n_sl, sl, cmp(n_sl,sl)
print 'TEST for error handling'
e_sl = nslice((0, 2, 1))
print
return
nsliceError = "Error in nslice:\n"
class nslice:
"""
slice object with additional methods.
Currently only access to start,stop and step attributes and a way
to compare slices.
"""
def __init__(self, sl):
"""
Initialize a new instance.
"""
if (type(sl) == type(1)):
self.start = sl
self.stop = sl+1
self.step = None
elif (type(sl) == type(slice(0,1,None))):
self.start = sl.start
self.stop = sl.stop
self.step = sl.step
else:
raise nsliceError, \
"Argument must be an integer or a slice object"
return
def __repr__(self):
return 'n'+str(self.__call__())
def __call__(self):
"""
returns the new slice object
"""
return slice(self.start,
self.stop,
self.step)
def __cmp__(self,other):
"""
gives 0 if both slices are identical
gives -1 if first slice is part of second one
gives 1 in all other cases
Problem is the handling of the step attribute. The above
is only true if the steps are the same.
"""
if (type(other) != type(slice(0,1,None))):
raise nsliceError, \
"Both arguments must be slice objects"
if ((self.start == other.start) and
(self.stop == other.stop)):
return cmp(self.step, other.step)
elif ((self.start >= other.start) and (self.stop <= other.stop)):
return -1
else:
return 1
if __name__ == "__main__":
test()
_______________
MATRIX-SIG - SIG on Matrix Math for Python
send messages to: matrix-sig@python.org
administrivia to: matrix-sig-request@python.org
_______________