1

I have read the below StackOverflow questions and my situation is similar but (I think) different:

My class creates what is meant to be an instance-level dictionary object. However, my constructor function provides a default value for that object. When I try to make an instance of my class with the default value, it suddenly behaves like it was class-level.

class store_a_dict:
    def __init__(self,dict_in={"A":0}):
        self.dict = dict_in

    def increment(self):
        self.dict["A"] += 1

    def print_me(self):
        print(self.dict)

test1 = store_a_dict({"A":3})
print("Initialised test1. Now test1 contains:")
test1.print_me()
test2 = store_a_dict()
print("Initialised test2 using default input. Now test2 contains:")
test2.print_me()
test2.increment()
print("Incremented test2. Now test2 contains:")
test2.print_me()
test3 = store_a_dict()
print("Initialised test3 using default input. Now test3 contains:")
test3.print_me()
print("We haven't touched test1, and it still contains:")
test1.print_me()

The code output is below. My expectation was that test3 should contain {'A': 0} after I initialised it using store_a_dict() with no inputs.

Initialised test1. Now test1 contains:
{'A': 3}
Initialised test2 using default input. Now test2 contains:
{'A': 0}
Incremented test2. Now test2 contains:
{'A': 1}
Initialised test3 using default input. Now test3 contains:
{'A': 1}
We haven't touched test1, and it still contains:
{'A': 3}

It seems like the obvious workaround is to change line 3 of my code to read self.dict = dict_in.copy(), but I want to understand why it works this way. Why is it perfectly happy to take in a value for dict_in when one is provided as part of a call to the class, and have it be isolated to the instance, but when I try to use the default value it suddenly seems to become a class-level object? Please help me understand this more deeply so I can avoid similar mistakes.

dks
  • 11
  • 2
  • Python picked a really dumb implementation of default argument values. No other language I'm aware of made the same mistake - reevaluation on every call is the overwhelmingly dominant approach. – user2357112 May 26 '19 at 02:49
  • Thanks for the quick response. The linked thread answers my question, I believe. Do I need to do anything now that my question has been marked as a duplicate? – dks May 26 '19 at 02:55
  • You can just leave the question as it is. – user2357112 May 26 '19 at 02:56

0 Answers0