Bizarre behavior with mutable default arguments

bukzor workitharder at gmail.com
Sat Dec 29 12:50:53 EST 2007


I've found some bizzare behavior when using mutable values (lists,
dicts, etc) as the default argument of a function. I want to get the
community's feedback on this. It's easiest to explain with code.

This example is trivial and has design issues, but it demonstrates a
problem I've seen in production systems:

def main(argv = ['TESTING']):
    'print out arguments with BEGIN and END'
    argv.insert(1, "BEGIN")
    argv.append("END")
    for arg in argv: print arg

if __name__ == '__main__':
    from sys import argv, exit
    exit(main(argv))


Now lets try this out at the terminal:

>>> import example
>>> example.main()
BEGIN
TESTING
END
>>> example.main(["TESTING"])
BEGIN
TESTING
END
>>> example.main()
BEGIN
BEGIN
TESTING
END
END
>>> example.main(["TESTING"])
BEGIN
TESTING
END

The function does different things if you call it with ["TESTING"] as
the argument, even though that is identical to the default value!! It
seems that default values are only allocated once. If the default
value is mutable and is changed during the function's execution, this
has the side effect of making the default value change on each
subsequent execution.

Is this functionality intended? It seems very unintuitive. This has
caused a bug in my programs twice so far, and both times I was
completely mystified until I realized that the default value was
changing.

I'd like to draw up a PEP to remove this from py3k, if I can get some
community backing.


--Buck



More information about the Python-list mailing list