0

Ok, so, I'm not really sure how to word this question in a single concise phrase, so if a mod can come up with a better title please fix it.

So lets say you have a module "testModule.py"

# testModule.py    
data = {'x': 1, 'y': 2, 'z': 3}

class A:
    def __init__(self):
        pass

class B(A):
    def __init__(self):
        self.classData = data

class C(B):
    def __init__(self):
        B.__init__(self)
        self.classData = {'x': 2, 'y': 2, 'z': 3}

and you import testModule in a file "test.py"

# test.py
import testModule

b = testModule.B()
c = testModule.C()

print test.data
print b.classData
print c.classData

when you run test.py you get:

{'x': 1, 'y': 2, 'z': 3}
{'x': 1, 'y': 2, 'z': 3}
{'x': 2, 'y': 2, 'z': 3}

That's expected, fine, and dandy...

But if you were to change class C in testModule to:

class C(B):
    def __init__(self):
        B.__init__(self)
        self.classData['x'] = 2

And then run test.py you get:

 {'x': 2, 'y': 2, 'z': 3}
 {'x': 2, 'y': 2, 'z': 3}
 {'x': 2, 'y': 2, 'z': 3}

So I guess my question is this: why when you change a dictionary belonging to a base module by referring to a single element in the dictionary does it change that element for all of the dictionaries of subsequent classes (I hope that that makes sense). It does not do that when you just redefine the dictionary. Please help as this problem is really starting to bug me.

It might me nice to know that these .py files are structured the way they are because I am experiencing this problem currently with a project, and my classes follow the same structure. Thanks all in advanced, Jeraldamo

  • 1
    Reason is python object reference technique. http://stackoverflow.com/questions/12797749/python-and-reference-passing-limitation/12797976#12797976 – Rahul Gautam Nov 02 '12 at 05:29
  • In your example case you using object from parent class in C, not defining it down there in C – Rahul Gautam Nov 02 '12 at 05:30

1 Answers1

3

Actually you are referencing a single global and mutable object in all the classes. So you will see the changes reflected in all of them. This is because you are changing the same object. You would need to copy() the dictionary for each class instance to get a unique copy of the global one.

self.classData = data.copy()

However, even that may cause you problems if the values of the dict are also mutable. This is because the copy() method only does a shallow copy. The safest thing to do is to make a deep copy, using the copy module's deepcopy function. Place this in your class initializer.

self.classData = copy.deepcopy(data)
Keith
  • 42,110
  • 11
  • 57
  • 76