1

** I have already seen these posts, but couldn't figure out how to resolve my problem: Python: Dictionary as instance variable "Least Astonishment" and the Mutable Default Argument

I create a dictionary and then I pass it to a class as an input parameter. The class has an interal function that manipulates the value of the input dictionary. The problem is that after instantiating the class, the values of the original dictionary will also change. Here is a simple example:

class foo(object):
    def __init__(self,myDict):
        self.myDict = myDict
        self.f()
    def f(self):
        for key in self.myDict.keys():
            self.myDict[key] += 1

d = {'a':1,'b':2}
print 'd (before passing to the class) = ',d
inst = foo(myDict = d)
print 'inst.myDict = ',inst.myDict
print 'd (after passing to the class) = ',d

and here is the output:

d (before passing to the class) =  {'a': 1, 'b': 2}
inst.myDict =  {'a': 2, 'b': 3}
d (after passing to the class) =  {'a': 2, 'b': 3}

As you can see the value of the original dictionary "d" has also changed after instantiating the class. How can I avoid this? I need to institute this class with d several times (while changing other input parameters) and don't want to redefine "d" every time I instantiate.

Community
  • 1
  • 1
user3076813
  • 499
  • 2
  • 6
  • 13
  • You are sharing a reference to a Python dictionary; use a copy if this was not intended; `dict.copy()` creates a shallow copy of a dictionary. – Martijn Pieters Aug 22 '14 at 15:12
  • In addition to the previous post you referred to on this issue, I found this very clear and illuminating: https://www.inkling.com/read/learning-python-mark-lutz-4th/chapter-18/argument-passing-basics – user3076813 Aug 22 '14 at 17:05

1 Answers1

3

In general, you need to pass a copy of the dict to your class -- Or you can make a copy within the class...

self.myDict = myDict.copy()
mgilson
  • 300,191
  • 65
  • 633
  • 696
  • I'm just curious to know if this solution works too when I deal with a list of class instances or with a dictionary where values are class instances? Will I need to somehow tell python to (deep) copy the class instances in addition to the dictionary itself? – user3076813 Aug 22 '14 at 17:34
  • @user3076813 -- this creates a _shallow_ copy. If you need a deep copy, then have a look at [`copy.deepcopy`](https://docs.python.org/2/library/copy.html#copy.deepcopy) – mgilson Aug 22 '14 at 20:36