B
bukzor
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:
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
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:
BEGINBEGIN
TESTING
ENDBEGINexample.main(["TESTING"])
TESTING
ENDBEGIN
BEGIN
TESTING
END
ENDexample.main(["TESTING"])
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