Optional parameter object re-used when instantiating multiple objects
castironpi at gmail.com
Mon Nov 17 02:58:59 CET 2008
On Nov 16, 7:28 am, Steve Holden <st... at holdenweb.com> wrote:
> George Sakkis wrote:
> > On Nov 16, 2:05 am, Arnaud Delobelle <arno... at googlemail.com> wrote:
> >> Steven D'Aprano <st... at REMOVE-THIS-cybersource.com.au> 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:
> Would you also retain the context surrounding the function declaration
> so it's obvious how it will be evaluated, or would you limit the default
> values to expressions with no bound variables?
> > 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
> "Less obvious" is entirely in the mind of the reader. However I can see
> far more justification for the behavior Python currently exhibits than
> the semantic time-bomb you are proposing.
It is too bad you are not better at sharing what you see. I would
like to see 'far more' of it, if it's there.
More information about the Python-list