I discovered a strange bug in my Python code recently. It took me a few minutes worth of digging to uncover something somewhat surprising, a side-effect to do with default parameters that is not obvious at first blush. Consider the following code:
If run with no parameters, it appears to have the expected and desired behaviour. Give it a parameter, and the line that appends a question will cause all instances to have the same question added. Obviously a bug, but why?
What’s happening is the default value for the
question parameter is evaluated at compile time to be an instance of an empty list. All instances then refer to this same empty list, so when one gets something appended, they all appear to get it. The solution is of course to have it default to
None and then construct a list when required.
Even when the default parameter is a function, it is still evaluated only the once, so its return value becomes a constant default value. It turns out that this is clearly documented (thanks Fred!) in the Python Language Reference: Section 7.5 Function definitions.
For someone used to doing funky stuff in C++ constructors (like yours truly), this might be a subtle gotcha.