Lists are weird when they are instance members

Discussion in 'Python' started by python newbie, Jan 3, 2004.

  1. hey,
    okay, I'm trying to figure out why my books: Quick Python, Python in a
    Nutshell, Python Cookbook and Learning Python don't say anything about the
    weird behavior of a list when you have one as an object instance member.

    for instance (my first pun of 2004), if I have,

    test.py
    ----------------

    global_filegroup_array = [] # array of filegroup objects

    class FileGroup:
    a = 0
    mylist = [] # here it is

    def put_stuff_in_my_list(self, anyfile):
    self.mylist.append( get just a single string from file) #
    pls excuse the psuedo

    def __init__(self):
    put_stuff_in_my_list(anyfile)

    def main(): # do ten times: instantiate the
    above object, and add to the global array
    for i in xrange(10):
    filegroup = FileGroup()
    global_filegroup_array.append(filegroup)


    # print the list contents
    print global_filegroup_array[0].mylist

    ------------ end of file

    Output is: [u'.string1', u'.string2', u'.string3' ] # only
    u'string1' should show up

    No matter which index I use into the global array, I always get ALL of
    the strings
    showing up. I should only get u'string1' showing up, and u'string2'
    if
    I used "[1].mylist"


    How I resolved it, is by slipping in

    self.mylist = []

    before

    put_stuff_in_my_list(anyfile)

    in __init__(self)

    Why should I have to empty out the list when it's a member of a newly
    instantiated object?

    thanks

    p.s. ( I'm actually not doing exactly the thing with the
    files, but instead iterating through a xml file with dom,
    debugging it showed the behavior )
     
    python newbie, Jan 3, 2004
    #1
    1. Advertising

  2. python newbie wrote:

    > test.py
    > ----------------
    >
    > global_filegroup_array = [] # array of filegroup objects
    >
    > class FileGroup:
    > a = 0
    > mylist = [] # here it is


    This is a class variable, not a member or instance variable. Make
    sure you know the difference.

    > def put_stuff_in_my_list(self, anyfile):
    > self.mylist.append( get just a single string from
    > file)


    This line creates a member variable "mylist" of the current instance
    "self" of class "FileGroup" as a copy of the class variable
    "FileGroup.mylist".

    Just create your member variables in the c'tor function __init__.
    This should solve all your problems (ok, at least this problem;)

    And btw. Python in a nutshell (I haven't read the other books you've
    mentioned) explains the differences between class and member
    variables.

    Mathias
     
    Mathias Waack, Jan 3, 2004
    #2
    1. Advertising

  3. python newbie

    Robin Becker Guest

    In article <ffHJb.5475$>, python
    newbie <> writes

    I think you're not grokking that using

    class A:
    mylist = []

    makes mylist a class attribute ie all instances share the same version
    of mylist. To get an instance version you need to assign self.mylist.
    That would normally be done using an __init__method. so

    class A:
    def __init__(self):
    self.mylist = []

    then each instance sets up its own empty list at creation time.

    Hope that helps.
    --
    Robin Becker
     
    Robin Becker, Jan 3, 2004
    #3
  4. In article <ffHJb.5475$>, python newbie wrote:
    > hey,
    > okay, I'm trying to figure out why my books: Quick Python, Python in a
    > Nutshell, Python Cookbook and Learning Python don't say anything about the
    > weird behavior of a list when you have one as an object instance member.
    >
    > for instance (my first pun of 2004), if I have,
    >
    > test.py
    > ----------------
    >
    > global_filegroup_array = [] # array of filegroup objects
    >
    > class FileGroup:
    > a = 0
    > mylist = [] # here it is


    mylist in this case is a class variable; what this means is that it is shared
    amongst all *instances* of the class. Only if an instance of the class rebinds
    mylist is it local to the particular class instance doing this.

    >
    > def put_stuff_in_my_list(self, anyfile):
    > self.mylist.append( get just a single string from file) #
    > pls excuse the psuedo


    Because lists are mutable, when you use mylist.append(...) you don't rebind
    mylist, but change its contents. Since mylist is a class variable, this
    change is available to the class as well as all instances of the class.

    >
    > def __init__(self):
    > put_stuff_in_my_list(anyfile)
    >
    > def main(): # do ten times: instantiate the
    > above object, and add to the global array
    > for i in xrange(10):
    > filegroup = FileGroup()
    > global_filegroup_array.append(filegroup)
    >
    >
    > # print the list contents
    > print global_filegroup_array[0].mylist
    >
    > ------------ end of file
    >
    > Output is: [u'.string1', u'.string2', u'.string3' ] # only
    > u'string1' should show up
    >
    > No matter which index I use into the global array, I always get ALL of
    > the strings
    > showing up. I should only get u'string1' showing up, and u'string2'
    > if
    > I used "[1].mylist"
    >
    >
    > How I resolved it, is by slipping in
    >
    > self.mylist = []
    >
    > before
    >
    > put_stuff_in_my_list(anyfile)
    >
    > in __init__(self)
    >
    > Why should I have to empty out the list when it's a member of a newly
    > instantiated object?


    Because __init__() is called when a class is about to be instantiated. You are
    masking the *class variable* mylist with a local *instance variable* of the
    same name. The latter is not shared amongst all instances of the class, but
    remains unique to the particular instance.

    Hope this helps,

    /Troels Therkelsen
     
    Troels Therkelsen, Jan 3, 2004
    #4
  5. thanks for the helpful replies.
    I guess I was just in confusion as to why I was able to leave alone the
    string variables in class FileGroup, such
    as sourceDir and destinDir, and nothing unpredictable happened with those,
    but with the list variable, I had to treat differently.
    But after I again read closely, Python In a Nutshell, I'm sure I will
    understand.


    "python newbie" <> wrote in message
    news:ffHJb.5475$...
    > hey,
    > okay, I'm trying to figure out why my books: Quick Python, Python in a
    > Nutshell, Python Cookbook and Learning Python don't say anything about the
    > weird behavior of a list when you have one as an object instance member.
    >
    > for instance (my first pun of 2004), if I have,
    >
    > test.py
    > ----------------
    >
    > global_filegroup_array = [] # array of filegroup objects
    >
    > class FileGroup:
    > a = 0
    > mylist = [] # here it is
    >
    > def put_stuff_in_my_list(self, anyfile):
    > self.mylist.append( get just a single string from file) #
    > pls excuse the psuedo
    >
    > def __init__(self):
    > put_stuff_in_my_list(anyfile)
    >
    > def main(): # do ten times: instantiate the
    > above object, and add to the global array
    > for i in xrange(10):
    > filegroup = FileGroup()
    > global_filegroup_array.append(filegroup)
    >
    >
    > # print the list contents
    > print global_filegroup_array[0].mylist
    >
    > ------------ end of file
    >
    > Output is: [u'.string1', u'.string2', u'.string3' ] # only
    > u'string1' should show up
    >
    > No matter which index I use into the global array, I always get ALL of
    > the strings
    > showing up. I should only get u'string1' showing up, and u'string2'
    > if
    > I used "[1].mylist"
    >
    >
    > How I resolved it, is by slipping in
    >
    > self.mylist = []
    >
    > before
    >
    > put_stuff_in_my_list(anyfile)
    >
    > in __init__(self)
    >
    > Why should I have to empty out the list when it's a member of a newly
    > instantiated object?
    >
    > thanks
    >
    > p.s. ( I'm actually not doing exactly the thing with the
    > files, but instead iterating through a xml file with dom,
    > debugging it showed the behavior )
    >
    >
    >
    >
    >
    >
    >
    >
     
    python newbie, Jan 3, 2004
    #5
  6. I didn't say that right. I meant to say that I now finally understood
    what's going on now, with your replies, but I will take a slight break from
    the app I'm writing, and do some ingesting of the core Python concepts.

    "python newbie" <> wrote in message
    news:VfIJb.5485$...
    > thanks for the helpful replies.
    > I guess I was just in confusion as to why I was able to leave alone the
    > string variables in class FileGroup, such
    > as sourceDir and destinDir, and nothing unpredictable happened with those,
    > but with the list variable, I had to treat differently.
    > But after I again read closely, Python In a Nutshell, I'm sure I will
    > understand.
    >
     
    python newbie, Jan 3, 2004
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Asfand Yar Qazi
    Replies:
    4
    Views:
    432
    Asfand Yar Qazi
    Nov 12, 2004
  2. Martin M.
    Replies:
    4
    Views:
    369
    Simon Brunning
    Dec 15, 2005
  3. =?UTF-8?B?w4FuZ2VsIEd1dGnDqXJyZXogUm9kcsOtZ3Vleg==

    List of lists of lists of lists...

    =?UTF-8?B?w4FuZ2VsIEd1dGnDqXJyZXogUm9kcsOtZ3Vleg==, May 8, 2006, in forum: Python
    Replies:
    5
    Views:
    444
    =?UTF-8?B?w4FuZ2VsIEd1dGnDqXJyZXogUm9kcsOtZ3Vleg==
    May 15, 2006
  4. hdixon
    Replies:
    3
    Views:
    676
    hdixon
    Jul 9, 2006
  5. Dave Rudolf
    Replies:
    1
    Views:
    320
    Kai-Uwe Bux
    May 17, 2006
Loading...

Share This Page