This issue was brought up to me in a conversation with my manager and I thought it would be a good idea to create a post about it. It may not be new to you but these posts are a sort of way for me to remember these sorts of things I may not run into very often. That said, the example problem was yanked out of Stack Overflow.
Context
When we want to give a function argument a default value, we may sometimes want/need to set the default to an empty dict. E.g.:
def f(value, key, hash={}):
hash[value] = key
return hash
print(f('a', 1))
print(f('b', 2))
Problem
We might expect the output of the code above to be:
{'a': 1}
{'b': 2}
But what we'd actually see is:
{'a': 1}
{'a': 1, 'b': 2}
Solution
The cause of the issue is stated in the Python Docs for argument values. There is a warning:
Important warning: The default value is evaluated only once. This makes a difference when the default is a mutable object such as a list, dictionary, or instances of most classes.
The issue applies to mutable default objects in general. So while list and
dictionary are common examples, it also includes things like set,
bytearray, or mutable class instances.
The recommendation, and solution, is the following:
def f(value, key, hash=None):
if hash is None:
hash = {}
hash[value] = key
return hash