Optional parameter object re-used when instantiating multiple objects

Steve Holden steve at holdenweb.com
Sun Nov 16 14:28:40 CET 2008

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.

Steve Holden        +1 571 484 6266   +1 800 494 3119
Holden Web LLC              http://www.holdenweb.com/

More information about the Python-list mailing list