On Fri, 8 May 2015 09:59 pm, Michael Welle wrote: > Hello, > > assume the following function definition: > > def bar(foo = []): > print("foo: %s" % foo) > foo.append("foo") > > It doesn't work like one would expect (or as I would expect ;-)). As I > understand it the assignment of the empty list to the optional parameter > foo take place when the function object is created, not when it is > called. I think from the perspective of a user this is very strange.
I think it is perfectly expected. Do you think that Python will re-compile the body of the function every time you call it? Setting the default is part of the process of compiling the function. If we have this function definition: def spam(eggs=long_complex_calculation()): pass do you expect the long complex calculation to be repeated every time you call the function? How about this definition: default = 23 def spam(eggs=default): pass del default print spam() Do you expect the function call to fail because `default` doesn't exist? My answers to those questions are all No. To me, it is not only expected, but desirable that function defaults are set once, not every time the function is called. This behaviour is called "early binding" of defaults. The opposite behaviour is called "late binding". If your language uses late binding, it is very inconvenient to get early binding when you want it. But if your language uses early binding, it is very simple to get late binding when you want it: just put the code you want to run inside the body of the function: # simulate late binding def spam(eggs=None): if eggs is None: # perform the calculation every time you call the function eggs = long_complex_calculation() default = 23 def spam(eggs=None): if eggs is None: # look up the global variable every time you call the function eggs = default On the rare times that you want to allow None as an ordinary value, you can create your own private sentinel value: _SENTINEL = object() def spam(eggs=_SENTINEL): if eggs is _SENTINEL: eggs = something_else -- Steven -- https://mail.python.org/mailman/listinfo/python-list