[Python-ideas] fixing mutable default argument values

Calvin Spealman ironfroggy at gmail.com
Mon Jan 15 03:58:00 CET 2007


There are a few problems here. Deep copy of the originally created
default argument can be expensive and would not work in any useful way
with non-literals as defaults, such as function calls or subscript
lookups or even simple attributes.

If any solution is possible, it would require a way to differentiate
between mutable and immutable objects, and evaluate the immutables for
every call. This brings on more problems as to when you do the initial
evaluation, if you then might do further evaluations depending on the
results of the first.

Any solution would be an unjust addition of expense to defaults.

On 1/14/07, Chris Rebert <cvrebert at gmail.com> wrote:
> If A.M. Kuchling's list of Python Warts is any indication, Python has
> removed many of the warts it once had. However, the behavior of mutable
> default argument values is still a frequent stumbling-block for newbies.
> It is also present on at least 3 different lists of Python's
> deficiencies ([0][1][2]).
>
> Example of current, unintuitive behavior (snipped from [0]):
>  >>> def popo(x=[]):
> ...     x.append(666)
> ...     print x
> ...
>  >>> popo()
> [666]
>  >>> popo()
> [666, 666]
>  >>> popo()
> [666, 666, 666]
>
> Whereas a newbie with experience with immutable default argument values
> would, by analogy, expect:
>  >>> popo()
> [666]
>  >>> popo()
> [666]
>  >>> popo()
> [666]
>
> In scanning [0], [1], [2], and other similar lists, I have only found
> one mediocre use-case for this behavior: Using the default argument
> value to retain state between calls. However, as [2] comments, this
> purpose is much better served by decorators, classes, or (though less
> preferred) global variables. Other uses are alluded to be equally
> esoteric and unpythonic.
>
> To work around this behavior, the following idiom is used:
> def popo(x=None):
>      if x is None:
>          x = []
>      x.append(666)
>      print x
>
> However, why should the programmer have to write this extra boilerplate
> code when the current, unusual behavior is only relied on by 1% of
> Python code?
>
> Therefore, I propose that default arguments be handled as follows in Py3K:
> 1. The initial default value is evaluated at definition-time (as in the
> current behavior).
> 2. That in a function call where the caller has not specified a value
> for an optional argument, Python calls
> copy.deepcopy(initial_default_value), and fills in the optional argument
> with the resulting value.
>
> This is fully backwards-compatible with the aforementioned workaround,
> and removes the need for the it, allowing one to write the first,
> simpler definition of popo().
>
> Comments?
>
> - Chris Rebert
>
>
> [0] 10 Python pitfalls (http://zephyrfalcon.org/labs/python_pitfalls.html)
> [1] Python Gotchas
> (http://www.ferg.org/projects/python_gotchas.html#contents_item_6)
> [2] When Pythons Attack
> (http://www.onlamp.com/pub/a/python/2004/02/05/learn_python.html?page=2)
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> http://mail.python.org/mailman/listinfo/python-ideas
>


-- 
Read my blog! I depend on your acceptance of my opinion! I am interesting!
http://ironfroggy-code.blogspot.com/



More information about the Python-ideas mailing list