Skip to content

Rhaptos Software Development

Personal tools
You are here: Home » Developer Blog » Ross's Bits » mutable defaults for function parameters considered evil

mutable defaults for function parameters considered evil mutable defaults for function parameters considered evil

Document Actions
Submitted by reedstrm. on 2009-12-16 11:48.
Providing a mutable type (like a list) as the default for a python function parameter can have unforeseen consequences.

Consider the lowly function def:

 >>> def addit(it, stuff=[]):
 ...     stuff.append(it)
 ...     return stuff
 ...
 >>> addit('this')
 ['this']
 >>> addit('that')
 ['this', 'that']
 >>> addit('theother')
 ['this', 'that', 'theother']
 >>> addit('thing2',['thing1'])
 ['thing1','thing2']
 >>> addit('onemore')
 ['this', 'that', 'theother', 'onemore']
 >>>

What's going on here?

Default params for functions are evaluated at function definition time, so our default for stuff is a single list, stored in addit.func_defaults. Each call to addit that uses the default uses the same list.

The way around this is to initialize stuff to None, and provide a fresh empty list:

 >>> def addit(it, stuff=None):
 ...     stuff = stuff or []
 ...     stuff.append(it)
 ...     return stuff
 ...
 >>> addit('this')
 ['this']
 >>> addit('that')
 ['that']
 >>> addit('theother')
 ['theother']
 >>> addit('thing',['thing2'])
 ['thing2', 'thing']
 >>> addit('thing2',['thing1'])
 ['thing1', 'thing2']
 >>> addit('onemore')
 ['onemore']

One last caveat: unless the caller is explicitly expecting the function to modify the passed in list, it's probably best to make a copy:

 >>> def addit(it, stuff=None):
 ...     stuff = stuff and stuff[:] or []
 ...     stuff.append(it)
 ...     return stuff
 ...