Optional parameter object re-used when instantiating multiple objects

Steve Holden steve at holdenweb.com
Mon Nov 17 03:27:43 CET 2008

Aaron Brady wrote:
> 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.

Well, briefly: it seems far simpler to me to use

def f(x=None):
  if x is None:
    x = <some value interpreted in the context of the current call>

than it does to use

def f(x=<some value to be interpreted in the context of the current call>):

particularly since at present the language contains no syntax for the
latter. But maybe I am focusing too much on the difficulty of compiling
whatever bizarre syntax is eventually adopted.

Understand, my point of view is biased by forty years of programming
experience, to the extent that I disagreed with Guido's proposal to make
integer division return a floating-point value. So I wouldn't
necessarily claim alignment with the majority.

Consider, though, the case were one argument value has to refer to
another. I would say the function body is the proper place to be doing
that computation. You appear to feel the def statement is the
appropriate place. If multiple statements are needed to perform the
argument initialization, how would you then propose the problem should
be solved?

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