简体   繁体   中英

Weird list behavior in class

I've written a class that has a list as a variable. I have a function that adds to that list and a function that outputs that list.

class MyClass:
    myList = []

    def addToList(self, myNumber):
        self.myList.append(myNumber)

    def outputList(self):
        for someNumber in self.myList:
            print someNumber

Now for some weird reason, if I declare two separate objects of the class:

ver1 = MyClass()
ver2 = MyClass()

and then call addToList on ver1:

ver1.addToList(3)

and then output ver2's list:

ver2.outputList()

I get 3 as output for version 2's list! What is happening?

Your syntax is wrong. You are using a class-static variable. Consider this:

class MyClass:
    myList = []    # Static variable

    def __init__(self):
        self.myRealList = []   # Member variable

myList is actually a part of the MyClass definition, and thus is visible not only by the class name, but all instances of that class as well:

c = MyClass()
c.myList = [1]
print MyClass.myList  # will print [1]

You need to declare regular "member variables" in the __init__ constructor.

Don't feel bad, I came to python from a C/C++/C# world, made this same mistake, and it confused me too at first.

The problem is that mylist is initialized when the file is parsed. So each subsequent initializations of MyClass will have the same reference to the same mylist.

class MyClass:
    myList = []

Instead you should initialize it with the class.

class MyClass:
    def __init__(self):
        self.myList = []

myList is actually a class variable (I don't know if that's the Pythonic term for it) because it is declared outside of any function.

To make a variable instance-local (once again, I don't know the proper term), you should initialize it in your init method like "self.myList = []".

Please edit any bad formatting on my part, I am on my phone.

There are several things going on here. You can have instance or class variables in python. In your example myList is a class variable which is static across all instances. There are also instance variables that are local to a class and you can override class variables with instance variables. Here is an example:

class Foo:
    bar = 'Hello' # Class variable

    def __init__(self):
        self.foobar = 'Hello World' # instance variable

    def createInstanceBar(self, x):
        self.bar = x # Override class variable and create instance variable

a = Foo()
b = Foo()
print a.bar # Prints Hello
print b.bar # Prints Hello

print a.foobar # Prints Hello World
print b.foobar # Prints Hello World

a.createInstanceBar('Hello New World')
print a.bar # Prints Hello New World
print b.bar # Prints Hello

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM