This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Attributes of type list are static
Type: Stage:
Components: Interpreter Core Versions: Python 2.6
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: Chris.Carter, michael.foord
Priority: normal Keywords:

Created on 2010-01-28 23:58 by Chris.Carter, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (5)
msg98483 - (view) Author: Chris Carter (Chris.Carter) Date: 2010-01-28 23:58
The test case at the end of this message seems to indicate that the list is being initialized only once for all wrapper instances.  I've tried to find anything about static members in Python and came up empty.  I also found no relevant existing bugs.

Expected output:
0 [0]
1 [1]
2 [2]
3 [3]

Actual output:
0 [0]
1 [0, 1]
2 [0, 1, 2]
3 [0, 1, 2, 3]

Test case:
i = 0
class Lister:

        list = []
        string = ""
        def __init__(self):
            global i
            self.list.append(i)
            self.string += str(i)
            i += 1
        def __str__(self):
            return "%s %s" % (self.string, self.list)

print Lister()
print Lister()
print Lister()
print Lister()
msg98484 - (view) Author: Michael Foord (michael.foord) * (Python committer) Date: 2010-01-29 00:12
The list in your example is a *class attribute* not an instance attribute, so yes it is only initialised once. You can still access it through the instance (self) because of Python member lookup rules.

If you want one list per instance then initialise it in __init__ instead of making it a class attribute.

In short, Python is not Java.
msg98487 - (view) Author: Chris Carter (Chris.Carter) Date: 2010-01-29 00:16
Then I must ask, why did the string attribute behave differently?  I added it to allow for that, and the behavior seems inconsistent.
msg98489 - (view) Author: Michael Foord (michael.foord) * (Python committer) Date: 2010-01-29 00:23
Because strings are immutable. Your list access (self.list.append) mutates the existing list in place.

Because strings are immutable you += is exactly equivalent to the following code:

    self.string = self.string + str(i)

The first lookup of self.string actually looks up the class attribute (because on a fresh instance there is no instance attribute). The class attribute is an empty string. You then create a new string by adding the empty string to str(i) and assign an *instance* attribute to str(i).

Because you haven't mutated the class attribute (strings are immutable) the next time round with a new instance the whole process repeats and the first lookup of self.string still finds the class attribute which is still an empty string.

With your example code try the following:

    print Lister.string
    print Lister()
    print Lister.string

You will see that the class attribute is unchanged in between instantiations. The += on immutable objects probably doesn't quite behave how you expect.
msg98499 - (view) Author: Chris Carter (Chris.Carter) Date: 2010-01-29 03:30
Ha, fun with language features.  Thanks for the detailed explanation. :)
History
Date User Action Args
2022-04-11 14:56:57adminsetgithub: 52048
2010-01-29 03:30:03Chris.Cartersetmessages: + msg98499
2010-01-29 00:23:52michael.foordsetmessages: + msg98489
2010-01-29 00:16:52Chris.Cartersetmessages: + msg98487
2010-01-29 00:12:55michael.foordsetstatus: open -> closed

nosy: + michael.foord
messages: + msg98484

resolution: not a bug
2010-01-28 23:58:36Chris.Cartercreate