Local dictionary variable unexpectedly persists beyond function

Viewed 23
def do_something(id, some_dict={}):
    some_dict[id] = 1
    print(list(some_dict.keys()))

do_something(1) # prints [1]
# print(some_dict) # this gives an error (as expected)
do_something(2) # prints [1, 2] -- but why?

I have a sample function here that shows the unexpected behaviour of do_something(2) printing [1,2]. Both functions don't pass in the optional argument some_dict, so I expect that some_dict is initialised to be an empty dictionary {} at the start of every function call.

Even if that is not the case (why would it not be however?), I would have expected some_dict to be a local variable, and it shouldn't be existing in the namespace after the function ends. I verified this by attempting to print(some_dict) and it expectedly raised an error.

In that case, why do the keys from some_dict persist from the first function to the second? Answers to this strange phenomenon (to me) would be very much appreciated!

1 Answers

Python’s default arguments are evaluated once when the function is defined, not each time the function is called. This means that if you use a mutable default argument(in your case it is a dict) and mutate it, you will and have mutated that object for all future calls to the function as well.

https://docs.python-guide.org/writing/gotchas/#mutable-default-arguments

Related