__slots__ and copy again: why does it work?

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

    __slots__ and copy again: why does it work?

    I remember from painful experience that copy.copy() won't really copy
    __slots__ members. But I have trouble explaning why the following code
    works:

    --- START---
    #!/usr/bin/env python

    import copy


    class Foo (object):
    __slots__ = 'i'

    def __init__ (self):
    self.i = 10


    class Bar (Foo):
    __slots__ = 'j'

    def __init__ (self):
    self.j = 20


    f1 = Foo()
    f2 = copy.copy(f1)

    print f2.i # why does it work?


    b1 = Bar()
    b2 = copy.copy(b1)

    print b2.j # why does it work?
    print b2.i # doesn't work, as expected

    --- END---


    Any insight is welcome!

  • fortepianissimo

    #2
    Re: __slots__ and copy again: why does it work?

    I should've mentioned this was tested on Python 2.4.2.


    fortepianissimo wrote:[color=blue]
    > I remember from painful experience that copy.copy() won't really copy
    > __slots__ members. But I have trouble explaning why the following code
    > works:
    >
    > --- START---
    > #!/usr/bin/env python
    >
    > import copy
    >
    >
    > class Foo (object):
    > __slots__ = 'i'
    >
    > def __init__ (self):
    > self.i = 10
    >
    >
    > class Bar (Foo):
    > __slots__ = 'j'
    >
    > def __init__ (self):
    > self.j = 20
    >
    >
    > f1 = Foo()
    > f2 = copy.copy(f1)
    >
    > print f2.i # why does it work?
    >
    >
    > b1 = Bar()
    > b2 = copy.copy(b1)
    >
    > print b2.j # why does it work?
    > print b2.i # doesn't work, as expected
    >
    > --- END---
    >
    >
    > Any insight is welcome![/color]

    Comment

    • fortepianissimo

      #3
      Re: __slots__ and copy again: why does it work?

      More weird observations: the following code does not work until you
      change the name of the member 'longer' to a one-char name, for example,
      'j':


      --- START ---
      #!/usr/bin/env python

      import copy


      class Foo (object):
      __slots__ = 'i'


      class Bar (Foo):
      __slots__ = 'longer'
      #__slots__ = 'j'


      b1 = Bar()
      b1.longer = 22
      #b1.j = 22

      b2 = copy.copy(b1)


      # doesn't work in Python 2.4.2
      # BUT if 'longer' is changed to 'j' in the entire file, then it works!
      print b2.longer
      #print b2.j

      --- END ---


      I've tried different names and concluded that as long as I used one
      character the code works. Anything longer than one character bombs.

      Why?

      Comment

      • fortepianissimo

        #4
        Re: __slots__ and copy again: why does it work?

        Mystery solved - when there's only one slot I should've used __slots__
        = ('i', ). Duh!

        So in short, __slots__ and copy.copy() work fine in Python 2.4.2.

        Comment

        • limodou

          #5
          Re: __slots__ and copy again: why does it work?

          26 Dec 2005 20:33:35 -0800, fortepianissimo <fortepianissim o@gmail.com>:[color=blue]
          > Mystery solved - when there's only one slot I should've used __slots__
          > = ('i', ). Duh!
          >
          > So in short, __slots__ and copy.copy() work fine in Python 2.4.2.
          >[/color]
          Hard works, but very useful :)


          --
          I like python!
          My Blog: http://www.donews.net/limodou
          NewEdit Maillist: http://groups.google.com/group/NewEdit

          Comment

          • fortepianissimo

            #6
            Re: __slots__ and copy again: why does it work?

            To be complete, the first code snippet, when modified as follows, works
            fine in Python 2.4.2:

            --- START ---
            #!/usr/bin/env python

            import copy

            class Foo (object):
            __slots__ = ('i', )

            def __init__ (self):
            self.i = 10

            class Bar (Foo):
            __slots__ = ('j', )

            def __init__ (self):
            super(Bar, self).__init__( )
            self.j = 20

            f1 = Foo()
            f2 = copy.copy(f1)

            print f2.i # works

            b1 = Bar()
            b2 = copy.copy(b1)

            print b2.j # works
            print b2.i # works
            --- END ---

            The last line didn't work last time because b2.i was never initialized.

            Comment

            Working...