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