views:

102

answers:

2

Hello guys.

I'm trying to understand an estrange behavior in Python.

I have the next python code:

class IntContainer:

    listOfInts = []

    def __init__(self, initListOfInts):

        for i in initListOfInts:
            self.listOfInts.append(i)

    def printInts(self):

        print self.listOfInts

if __name__ == "__main__":

    intsGroup1 = [1,2,3,4]
    intsGroup2 = [4,5,6,7]

    intsGroups = [intsGroup1,intsGroup2]

    intsContainers = []

    for ig in intsGroups:
        newIntContainer = IntContainer(ig)
        intsContainers.append(newIntContainer)

    for ic in intsContainers:
        print ic.listOfInts

I expect to get something like:

[1, 2, 3, 4]
[4, 5, 6, 7]

But i get:

[1, 2, 3, 4, 4, 5, 6, 7]
[1, 2, 3, 4, 4, 5, 6, 7]

I have check the next question:

http://stackoverflow.com/questions/1876905/why-is-python-reusing-a-class-instance-inside-in-function

And a lot of Python reference, but I can not understand what is happening. I think is related with the newIntContainer identifier reutilization, but I do not understand it deeply.

Why Python appears to reused the last reference for the new object, even if I have added it to a permanent list? What can I do to resolve this behavior?

Thanks ;)

+5  A: 

Since you made listOfInts a class variable, that's what self.listOfInts is accessing, whatever self instance it may be; so, all the appends are going to the same list.

If that's not what you want, you need to make listOfInts an instance variable, for example by assigning self.listOfInts = [] at the start of the __init__ method.

Alex Martelli
Thanks a lot...I came from C++, PHP and others where you do not have something like class-shared variables (class variable)... I just thought I was defining a regular object parameter (instance variable)...
fjfnaranjo
Actually, both C++ and PHP have class (static) fields.
Matthew Flaschen
+2  A: 

listOfInts has been defined as a class variable.

Class variables are shared by all the instances of the class.

This behavior is useful if you want to save class-related state (a typical example would be when you want to know the number of instances of the class created.

If you want listOfInts to be unique for each instance, then you should define it in init or other method of the class as self.listOfInts

joaquin