how to deepcopy a slice object?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Alexandre Guimond

    #1

    how to deepcopy a slice object?

    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\li b\copy.py", line 204, in deepcopy
    y = _reconstruct(x, rv, 1, memo)
    File "C:\Program Files\Python\li b\copy.py", line 336, in _reconstruct
    y = callable(*args)
    File "C:\Program Files\Python\li b\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.

  • Simon Forman

    #2
    Re: how to deepcopy a slice object?

    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.deepcop y( slice( 1, 10, 2 ) )
    Traceback (most recent call last):
    File "<stdin>", line 1, in ?
    File "C:\Program Files\Python\li b\copy.py", line 204, in deepcopy
    y = _reconstruct(x, rv, 1, memo)
    File "C:\Program Files\Python\li b\copy.py", line 336, in _reconstruct
    y = callable(*args)
    File "C:\Program Files\Python\li b\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

    Comment

    • Alexandre Guimond

      #3
      Re: how to deepcopy a slice object?

      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_parame ters
      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_parame ters

      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\li b\copy.py", line 204, in deepcopy
      y = _reconstruct(x, rv, 1, memo)
      File "C:\Program Files\Python\li b\copy.py", line 336, in _reconstruct
      y = callable(*args)
      File "C:\Program Files\Python\li b\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

      Comment

      • Duncan Booth

        #4
        Re: how to deepcopy a slice object?

        Simon Forman wrote:
        Why would you want to [deep]copy a slice object?
        I would guess the original poster actually wanted to copy a data structure
        which includes a slice object somewhere within it. That is a perfectly
        reasonable albeit somewhat unusual thing to want, however it doesn't work.

        Similarly in Python 2.4 you cannot deepcopy functions. That has been fixed
        in Python 2.5 but I guess nobody has tried deepcopying slices before so
        they haven't been fixed.

        Comment

        • Simon Forman

          #5
          Re: how to deepcopy a slice object?

          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_parame ters
          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_parame ters
          >
          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.deepcop y( slice( 1, 10, 2 ) )
          Traceback (most recent call last):
          File "<stdin>", line 1, in ?
          File "C:\Program Files\Python\li b\copy.py", line 204, in deepcopy
          y = _reconstruct(x, rv, 1, memo)
          File "C:\Program Files\Python\li b\copy.py", line 336, in _reconstruct
          y = callable(*args)
          File "C:\Program Files\Python\li b\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__(se lf, 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__(se lf):

          state = self.__dict__.c opy()

          # 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__(se lf, state):

          # Recreate the slice objects.
          state['slicex'] = slice(*state['slicex'])
          state['slicey'] = slice(*state['slicey'])

          self.__dict__.u pdate(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.DeepCopy able instance at 0xb7d5cb2c>
          |>d0.rec.rec #etc...
          <delme.DeepCopy able instance at 0xb7d5cb2c>
          |>d1 = deepcopy(d0)
          |>d1
          <delme.DeepCopy able instance at 0xb7d7878c>
          |>d1.rec
          <delme.DeepCopy able 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__(se lf):
          state = self.__dict__.c opy()

          # 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(a ttr)

          return state

          def __setstate__(se lf, state):

          slices = state.pop('slic es')

          # Recreate the slice objects.
          for attr in slices:
          state[attr] = slice(*state[attr])

          self.__dict__.u pdate(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

          Comment

          • Simon Forman

            #6
            Re: how to deepcopy a slice object?

            Duncan Booth wrote:
            Simon Forman wrote:
            >
            Why would you want to [deep]copy a slice object?
            >
            I would guess the original poster actually wanted to copy a data structure
            which includes a slice object somewhere within it. That is a perfectly
            reasonable albeit somewhat unusual thing to want, however it doesn't work.
            I figured it was either something like that or something really wacky.
            :-) Either way I was curious.
            Similarly in Python 2.4 you cannot deepcopy functions. That has been fixed
            in Python 2.5 but I guess nobody has tried deepcopying slices before so
            they haven't been fixed.
            Shows how unusual it is.


            Since slice objects appear to be immutable:

            |>s = slice(1)
            |>s
            slice(None, 1, None)
            |>s.start = 1
            Traceback (most recent call last):
            File "<stdin>", line 1, in ?
            TypeError: 'slice' object has only read-only attributes (assign to
            ..start)

            etc...

            fixing copy and deepcopy for slices would involve adding slice to the
            tuple in this for statement in copy.py (starts on line 115 in my
            version Python 2.4.3):

            for t in (types.NoneType , int, long, float, bool, str, tuple,
            frozenset, type, xrange, types.ClassType ,
            types.BuiltinFu nctionType):
            d[t] = _copy_immutable


            and, lower down, around line 214, adding a line like this:

            d[types.SliceType] = _deepcopy_atomi c


            I think I'll send a patch in in awhile. ;-)

            Peace,
            ~Simon

            Comment

            • Alexandre Guimond

              #7
              Re: how to deepcopy a slice object?

              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_parame ters
              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_parame ters

              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\li b\copy.py", line 204, in deepcopy
              y = _reconstruct(x, rv, 1, memo)
              File "C:\Program Files\Python\li b\copy.py", line 336, in _reconstruct
              y = callable(*args)
              File "C:\Program Files\Python\li b\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__(se lf, 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__(se lf):
              >
              state = self.__dict__.c opy()
              >
              # 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__(se lf, state):
              >
              # Recreate the slice objects.
              state['slicex'] = slice(*state['slicex'])
              state['slicey'] = slice(*state['slicey'])
              >
              self.__dict__.u pdate(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.DeepCopy able instance at 0xb7d5cb2c>
              |>d0.rec.rec #etc...
              <delme.DeepCopy able instance at 0xb7d5cb2c>
              |>d1 = deepcopy(d0)
              |>d1
              <delme.DeepCopy able instance at 0xb7d7878c>
              |>d1.rec
              <delme.DeepCopy able 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__(se lf):
              state = self.__dict__.c opy()
              >
              # 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(a ttr)
              >
              return state
              >
              def __setstate__(se lf, state):
              >
              slices = state.pop('slic es')
              >
              # Recreate the slice objects.
              for attr in slices:
              state[attr] = slice(*state[attr])
              >
              self.__dict__.u pdate(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

              Comment

              • Simon Forman

                #8
                Re: how to deepcopy a slice object?

                Alexandre Guimond wrote:
                thx for all the help simon. good ideas i can work with.
                >
                thx again.
                >
                alex.
                >
                You're very welcome, a pleasure. ;-)

                ~Simon

                Comment

                Working...