Bizarre behavior with mutable default arguments

NickC ncoghlan at gmail.com
Tue Jan 1 00:26:38 EST 2008


On Jan 1, 3:22 am, Arnaud Delobelle <arno... at googlemail.com> wrote:
> On Dec 31, 10:58 am, Odalrick <odalr... at hotmail.com> wrote:
>
> > I'm surprised noone has said anything about the why of default
> > mutables. I think it is becasue it isn't easy to do it an other way.
>
> [...]
>
> There is an easy enough way: evaluate default values when the function
> is called rather than when it is defined.  This behaviour comes with
> its own caveats as well I imagine, and it's not 'as easy' to implement
> as the current one.

As Odalrick notes, there is no way to give different calls to a
function their own copies of mutable default arguments without re-
evaluating the defaults every time the function is called. The
horrendous performance implications mean that that simply isn't going
to happen. So the status quo, where the defaults are calculated once
when the function is defined and the result cached in the function
object is unlikely to change.

> What's good about the current behaviour is that it is easy to reason
> with (once you know what happens), even though you almost have to get
> bitten once.  But using this to have static variable is extremely ugly
> IMHO.

The only thing it doesn't give you is a static variable that isn't
visible to the caller. Py3k's keyword-only arguments (PEP 3102) will
make those cases a little tidier, since it won't be possible to
accidentally replace the static variables by providing too many
positional arguments.

I believe the suggestion of permitting static variables after the **
entry in a function's parameter list was raised during the PEP 3102
discussions, but never gained much traction over a '_cache={}' keyword-
only argument approach (and the latter has the distinct advantage of
being *much* easier to test, since you can override the cache from the
test code to ensure it is being handled correctly).

Cheers,
Nick.




More information about the Python-list mailing list