def foo(x = ):If you think about the def statement as a declaration, the answer is obvious - it should print
[ 'bar' ]but in fact it prints
[ 'bar' ]
[ 'bar' ]Why ? Because in Python def is an executable statement, which means that the list of arguments for the method to be created (x) and most importantly their default values () are themselves nothing but arguments to def. Something like this:
[ 'bar', 'bar' ]
foo = def(x, default_x)and when this gets executed, default_x is bound to something that at that point evaluates to an empty list, but remains mutable. Then, whenever the created foo is executed, the append method modifies the contents of default_x - effectively the "default value" of x.
This sounds strange, but is clearly documented in the language reference, quote from http://docs.python.org/ref/function.html
Default parameter values are evaluated when the function definition is executed. This means that the expression is evaluated once, when the function is defined, and that that same "pre-computed" value is used for each call. This is especially important to understand when a default parameter is a mutable object, such as a list or a dictionary: if the function modifies the object (e.g. by appending an item to a list), the default value is in effect modified.The spec suggests using None for all the default parameters, but you should have no problem using any immutable objects as well. For example:
def foo(x = None):where x is None, or
print (x or ) + [ "bar" ]
def foo(x = ()):Phew, I've been lucky using None's so far...
# oops, no append method
print x + ( "bar", )