0

I encountered this strange, counter-intuitive behaviour when assigning a default value to a dictionary parameter of a function. Suppose I have the following code:

def test_fn(d = dict()):
    import time
    for k, v in d.items():
        print(f'{k}\t{v}')
    d[time.ctime()] = 'AAAAAAAAAAGH'

Repeatedly running this function in my favourite IDE produces the following output:

>>> test_fn()

>>> test_fn()
Fri Dec  7 21:35:31 2018        AAAAAAAAAAGH

>>> test_fn()
Fri Dec  7 21:35:31 2018        AAAAAAAAAAGH
Fri Dec  7 21:35:32 2018        AAAAAAAAAAGH

>>> test_fn()
Fri Dec  7 21:35:31 2018        AAAAAAAAAAGH
Fri Dec  7 21:35:32 2018        AAAAAAAAAAGH
Fri Dec  7 21:35:34 2018        AAAAAAAAAAGH

>>> test_fn()
Fri Dec  7 21:35:31 2018        AAAAAAAAAAGH
Fri Dec  7 21:35:32 2018        AAAAAAAAAAGH
Fri Dec  7 21:35:34 2018        AAAAAAAAAAGH
Fri Dec  7 21:35:35 2018        AAAAAAAAAAGH

et cetera. Now, to my intuition, explicitly assigning d = dict() as a default parameter should create a new instance of the dict class every time the function is run, and certainly this variable should only exist locally. Indeed, if I try and access d outside of test_fn, I of course get a NameError:

>>> d
Traceback (most recent call last):

File "<ipython-input-9-e983f374794d>", line 1, in <module>
d

NameError: name 'd' is not defined

And yet clearly Python is treating d as a global object in some sense, because it grows whenever the function is run.

Does anyone have any explanation for this behaviour? It seems quite non-Pythonic to me. Is this a deliberate design feature? Regardless of whether it is good practice to silently pass an empty dict as default, is there a way to actually force Python to create a new one every time the function runs?

  • 2
    see also [this](https://docs.python-guide.org/writing/gotchas/#mutable-default-arguments) helpful link – charlie80 Dec 07 '18 at 10:56
  • @charlie80 Awesome, thank you. Surprising that I have been writing Python code for so long and yet have never encountered this feature of the language! But it does make sense. The other 'gotchas' in that list you linked are equally fascinating. – Michael Cromer Dec 07 '18 at 11:01

0 Answers0