__slots__ and copy again: why does it work?

Discussion in 'Python' started by fortepianissimo, Dec 26, 2005.

  1. 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, Dec 26, 2005
    #1
    1. Advertisements

  2. I should've mentioned this was tested on Python 2.4.2.
     
    fortepianissimo, Dec 26, 2005
    #2
    1. Advertisements

  3. 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?
     
    fortepianissimo, Dec 27, 2005
    #3
  4. 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.
     
    fortepianissimo, Dec 27, 2005
    #4
  5. fortepianissimo

    limodou Guest

    Hard works, but very useful :)
     
    limodou, Dec 27, 2005
    #5
  6. 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.
     
    fortepianissimo, Dec 27, 2005
    #6
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.