Static class variables in Python -- Lists & Objects

3.9k views Asked by At

I'm new to Python, with more of a Java background. I understand the concept of static class variables in Python, but it's come to my attention that lists and objects don't work the same way a string would, for example - they're shared between instances of a class.

In other words:

class box ():

    name = ''
    contents = []

    def __init__ (self, name):
        self.name = name

    def store (self, junk):
        self.contents.append(junk)

    def open (self):
        return self.contents

Now if I create two instances and try to add things to them:

a = box('Box A')
b = box('Box B')

a.store('apple')
b.store('berry')

print a.open()
print b.open()

Output:

['apple','berry']
['apple','berry']

It's very clear they're shared between the two instances of box.

Now I can get around it by doing the following:

def store (self, junk):
    temp = self.contents
    temp.append(junk)
    self.contents = temp

But is there a cleaner/more conventional way? Can someone explain why this happens?

2

There are 2 answers

1
Iron Fist On BEST ANSWER

The Key word self makes them independent as if you are saying, self.name, belongs to the current instance of box() class:

class box ():

    def __init__ (self, name):
        self.name = name
        self.contents = []

    def store (self, junk):
        self.contents.append(junk)

    def open (self):
        return self.contents
0
Eric Levieil On

Both variables are class variables in your case. However, you set the string differently for the objects A and B, actually you are initializing them again. The list on the other hand is not initialized again so the lists from both object A and B point to the same object in memory. Appending items thus appends items to the same list in memory. Hence, the result.

You want to write this:

class box ():


    def __init__ (self, name):
        self.name = name
        self.contents = []

    def store (self, junk):
        self.contents.append(junk)

    def open (self):
        return self.contents