thx for all the help simon. good ideas i can work with. thx again.
alex. Simon Forman wrote: > Alexandre Guimond wrote: > > Here is my reason: > > > > I have an object that contrains a 2D regular grid (matrix). In this > > regular grid, I place points at regular intervals. In essence, i have > > something like (my code is obviously more complex, this is just to show > > what I want to do) > > > > obj.grid = numpy.zeros( ( 100, 100 ) ) > > obj.grid[ obj.y1: obj.y2 : obj.ys, obj.x1 : obj.x2 : obj.xs ] = > > embedded_parameters > > result = somefunc( obj.grid ) > > > > My goal was to reduce the number of elements in my obj object by > > replacing y1, y2, ys, and x1, x2, xs by 2 slice objects, and then do: > > > > obj.grid[ obj.slicey, obj.slicex ] = embedded_parameters > > > > But when I do this and then try to deepcopy my object, it doesn't work, > > as in the example below. > > > > Its not a big thing. I just liked the idea of having less elements in > > my obj class and actually modeling my slice concept by a slice object, > > specially since i'm going to 3D and 4D grid, and its somewhat annoying > > to carry so many indices in my class definition. > > > > Simon Forman wrote: > > > Alexandre Guimond wrote: > > > > Hi all, > > > > > > > > i'm trying to deepcopy a slice object but i get the following error. > > > > Does anyone know a workaround? > > > > > > > > ActivePython 2.4.3 Build 12 (ActiveState Software Inc.) based on > > > > Python 2.4.3 (#69, Apr 11 2006, 15:32:42) [MSC v.1310 32 bit (Intel)] > > > > on win32 > > > > Type "help", "copyright", "credits" or "license" for more information. > > > > >>> import copy > > > > >>> copy.deepcopy( slice( 1, 10, 2 ) ) > > > > Traceback (most recent call last): > > > > File "<stdin>", line 1, in ? > > > > File "C:\Program Files\Python\lib\copy.py", line 204, in deepcopy > > > > y = _reconstruct(x, rv, 1, memo) > > > > File "C:\Program Files\Python\lib\copy.py", line 336, in _reconstruct > > > > y = callable(*args) > > > > File "C:\Program Files\Python\lib\copy_reg.py", line 92, in > > > > __newobj__ > > > > return cls.__new__(cls, *args) > > > > TypeError: slice expected at least 1 arguments, got 0 > > > > > > > > thx for any help. > > > > > > Why would you want to [deep]copy a slice object? > > > > > > Anyway, I don't know much about them, other than that they are > > > slightly unusual objects that play a very restricted role in python, > > > rather like the Ellipsis. > > > > > > Workarounds are possible, I think, but really you almost certainly > > > don't need to do this. > > > > > > Peace, > > > ~Simon > > Ah, so you *do* want to deepcopy slice objects.. Neat. :-) > > I can't do that, but I can show you a couple of ways to deepcopy > objects that have slices as attributes. > > First, if the __init__() method and its args are sufficient to recreate > your objects then you could do something like this: > > class DeepCopyable0: > > def __init__(self, x, y, z, a, b, c): > self.slicex = slice(x, y, z) > self.slicey = slice(a, b, c) > > def __deepcopy__(self, memo): > > # Create local vars for brevity. > sx, sy = self.slicex, self.slicey > > # Create a new DeepCopyable0 instance. > return DeepCopyable0( > sx.start, sx.stop, sx.step, > sy.start, sy.stop, sy.step > ) > > |>> d0 = DeepCopyable0(1, 2, 3, 4, 5, 6) > |>> d0.slicex, d0.slicey > (slice(1, 2, 3), slice(4, 5, 6)) > |>> d1 = deepcopy(d0) > |>> d1.slicex, d1.slicey > (slice(1, 2, 3), slice(4, 5, 6)) > > Otherwise, another way to do it would be to provide the pickling > protocol: > > class DeepCopyable1: > > def __init__(self, x, y, z, a, b, c): > # Pretend this was something more complicated. > self.slicex = slice(x, y, z) > self.slicey = slice(a, b, c) > > def __getstate__(self): > > state = self.__dict__.copy() > > # Create local vars for brevity. > sx, sy = self.slicex, self.slicey > > # Save the indices rather than the slices. > state['slicex'] = sx.start, sx.stop, sx.step > state['slicey'] = sy.start, sy.stop, sy.step > > return state > > def __setstate__(self, state): > > # Recreate the slice objects. > state['slicex'] = slice(*state['slicex']) > state['slicey'] = slice(*state['slicey']) > > self.__dict__.update(state) > > > |>> d0 = DeepCopyable1(1, 2, 3, 4, 5, 6) > |>> d0.slicex, d0.slicey > (slice(1, 2, 3), slice(4, 5, 6)) > |>> d1 = deepcopy(d0) > |>> d1.slicex, d1.slicey > (slice(1, 2, 3), slice(4, 5, 6)) > > Circular references seem work fine here too. Observe: > > |>> d0 = DeepCopyable1(1, 2, 3, 4, 5, 6) > |>> d0.rec = d0 > |>> d0 > <delme.DeepCopyable instance at 0xb7d5cb2c> > |>> d0.rec.rec #etc... > <delme.DeepCopyable instance at 0xb7d5cb2c> > |>> d1 = deepcopy(d0) > |>> d1 > <delme.DeepCopyable instance at 0xb7d7878c> > |>> d1.rec > <delme.DeepCopyable instance at 0xb7d7878c> > > Since you're going to be using more dimensions, you could make python > do the work for you rather than cutting and pasting: > > class DeepCopyable2: > > # __init__() omitted... > > def __getstate__(self): > state = self.__dict__.copy() > > # Keep track of the slice attributes > slices = state['slices'] = [] > > # Convert slices to indices. > for attr, s in state.items(): > if isinstance(s, slice): > state[attr] = s.start, s.stop, s.step > slices.append(attr) > > return state > > def __setstate__(self, state): > > slices = state.pop('slices') > > # Recreate the slice objects. > for attr in slices: > state[attr] = slice(*state[attr]) > > self.__dict__.update(state) > > > (I copied over the __init__() method from DeepCopyable for this > example.) > |>> from delme import * > |>> d0 = DeepCopyable2(1, 2, 3, 4, 5, 6) > |>> d1 = deepcopy(d0) > |>> d1.slicex, d1.slicey > (slice(1, 2, 3), slice(4, 5, 6)) > > HTH. :) > > I haven't used numpy (yet) and I've never explicitly used slice > objects, so the idea of storing and copying them struck me funny. I > find it very interesting and amusing that someone somewhere has a use > for them like this. > > Peace, > ~Simon -- http://mail.python.org/mailman/listinfo/python-list