Question

When running following code in python, i create 2 objects of one class, that contains a list object:

class Test():
    def run(self):
        obj1 = klasse("Werner")                       
        obj2 = klasse("Franz")  

        print obj1.name
        print obj2.name
        obj2.add_name("Thomas")
        print obj2.name

class klasse(object):
    name = [];

    def __init__(self, value):
        self.name.append(str(value))

    def add_name(self, value):
        self.name.append(str(value))

if __name__ == "__main__":
    Test().run()

this returns in console:

['Werner', 'Franz']
['Werner', 'Franz']
['Werner', 'Franz', 'Thomas']

The Question: it seems to be the same list object in the two created klasse.objects. Whats the solution to isolate the name lists in every created object?

The console output should be:

['Werner']
['Franz']
['Franz', 'Thomas']
Was it helpful?

Solution

The implementation for your klasse should be like the following :

class klasse(object):

    #  name = [] if this was the case, the name would be a class variable, 
    #  and all instances would share it

    def __init__(self, value):
        self.name = [] #  but now it is a separate for each instance
        self.add_name(value)

    def add_name(self, value):
        self.name.append(str(value))

edit: incorporated @Jon Clements's suggestion.

OTHER TIPS

I just ran into this a couple of hours ago.

As the comments indicate when you define a variable inside a class but outside of a method of the class, that is a class level variable. Class level variables are the equivalent of static variables in other languages. There exists only one copy of the variable that is shared by all instances of that class. Interestingly enough, the variable also exists when there is no instance of the class. With your existing code base, try print klasse.name.

If you define a variable inside a method of a class, the variable unique to the instance of the class that defined it. To get the effect desired, you need to create and initialize self.name inside the __init__ method. This will create a unique instance of the variable in each instance of the class.

One side note, it is considered best practice in python and most other OO languages that class names be capitalized.

If you don't prepend with self. the variable will be a class variable, not an instance variable, meaning that for each object, the value will be the same. For this case, to make name an instance variable, you would do the following:

self.name = []

In case this was not evident in your testing, you cannot declare self.myVariable outside of a function.

In class Klasse, name variable is class level variable so before creating new instance of that class first check whether name list is empty or not. If not empty then make it empty in init() as this function called every time instance of that class being created.

>>> class klasse(object):
...     name = []
...     def __init__(self, value):
...         if self.name:
...             self.name = []
...         self.name = [value]
...     def add_name(self, value):
...         self.name.append(str(value))
...     
>>> class Test():
...     def run(self):
...         obj1 = klasse("Werner")
...         obj2 = klasse("Franz")
... 
...         print obj1.name
...         print obj2.name
...         obj2.add_name("Thomas")
...         print obj2.name
...     

>>> Test().run()
['Werner']
['Franz']
['Franz', 'Thomas']
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top