On Nov 16, 2:05 am, Arnaud Delobelle <[EMAIL PROTECTED]> wrote: > Steven D'Aprano <[EMAIL PROTECTED]> writes: > > On Sat, 15 Nov 2008 01:40:04 -0800, Rick Giuly wrote: > > >> Hello All, > > >> Why is python designed so that b and c (according to code below) > >> actually share the same list object? It seems more natural to me that > >> each object would be created with a new list object in the points > >> variable. > > > That's not natural *at all*. You're initialising the argument "points" > > with the same list every time. If you wanted it to have a different list > > each time, you should have said so. Don't blame the language for doing > > exactly what you told it to do. > > Come on. The fact that this questions comes up so often (twice in 24h) > is proof that this is a surprising behaviour. I do think it is the > correct one but it is very natural to assume that when you write > > def foo(bar=[]): > bar.append(6) > ... > > you are describing what happens when you _call_ foo, i.e.: > > 1. if bar is not provided, make it equal to [] > 2. Append 6 to bar > 3. ...
+1. Understanding and accepting the current behavior (mainly because of the extra performance penalty of evaluating the default expressions on every call would incur) is one thing, claiming that it is somehow natural is plain silly, as dozens of threads keep showing time and time again. For better or for worse the current semantics will probably stay forever but I wish Python grows at least a syntax to make the expected semantics easier to express, something like: def foo(bar=`[]`): bar.append(6) where `expr` would mean "evaluate the expression in the function body". Apart from the obvious usage for mutable objects, an added benefit would be to have default arguments that depend on previous arguments: def foo(x, y=`x*x`, z=`x+y`): return x+y+z as opposed to the more verbose and less obvious current hack: def foo(x, y=None, z=None): if y is None: y = x*x if z is None: z = x+y return x+y+z George -- http://mail.python.org/mailman/listinfo/python-list