28

Here's a function. My intent is to use keyword argument defaults to make the dictionary an empty dictionary if it is not supplied.

>>> def f( i, d={}, x=3 ) :
...     d[i] = i*i
...     x += i
...     return x, d
... 
>>> f( 2 )
(5, {2: 4})

But when I next call f, I get:

>>> f(3)
(6, {2: 4, 3: 9})

It looks like the keyword argument d at the second call does not point to an empty dictionary, but rather to the dictionary as it was left at the end of the preceding call. The number x is reset to three on each call.

Now I can work around this, but I would like your help understanding this. I believed that keyword arguments are in the local scope of the function, and would be deleted once the function returned. (Excuse and correct my terminology if I am being imprecise.)

So the local value pointed to by the name d should be deleted, and on the next call, if I don't supply the keyword argument d, then d should be set to the default {}. But as you can see, d is being set to the dictionary that d pointed to in the preceding call.

What is going on?

Is the literal {} in the def line in the enclosing scope?

This behavior is seen in 2.5, 2.6 and 3.1.

A J
  • 3,970
  • 14
  • 38
  • 53
Andrej Panjkov
  • 1,448
  • 2
  • 13
  • 17
  • 4
    That is a typical python gotcha: [Mutable defaults for function/method arguments](http://pythonconquerstheuniverse.wordpress.com/category/python-gotchas/) – Ocaso Protal Apr 19 '11 at 07:27

1 Answers1

5
>>> def f(i, d=None, x=3):
...     if not d:
...         d={}
...     d[i] = i*i
...     x += i
...     return x,d
... 
>>> f(2)
(5, {2: 4})
>>> f(3)
(6, {3: 9})
>>> 
dting
  • 38,604
  • 10
  • 95
  • 114