Optional parameter object re-used when instantiating multiple objects

Aaron Brady castironpi at gmail.com
Sun Nov 16 21:16:01 EST 2008


On Nov 16, 12:52 am, Steven D'Aprano <st... at REMOVE-THIS-
cybersource.com.au> wrote:
> On Sat, 15 Nov 2008 21:29:22 -0800, Aaron Brady wrote:
...
> If you want to be pedantic, then my "answer" (which you seem to approve
> of) doesn't correspond to either of the original poster's questions. If
> you're going to be pedantic, then be pedantic all the way, and criticize
> me for answering a question that wasn't asked :-P

Not pedantic.  He was questioning the reasons and motivation.

...
> Actually, the correct answer to "Why?" would be "Because that's the
> decision Guido van Rossum made back in the early 1990s when he first
> started designing Python". That of course leads to the obvious question
> "Why did he make that decision?", and the answer to that is:
>
> * it leads to far more efficient performance when calling functions;
>
> E.g. if the default value is expensive to calculate, it is better to
> calculate it once, when the function is created, than every single time
> the function is called.

It is best to calculate it just how many times you need to, and no
more.

> Additionally, the effbot once mentioned in a similar thread that there
> are real performance benefits in the Python VM from binding the default
> value once only. I don't know the exact details of that, but I trust
> Fredrik knows what he's talking about.
>
> * it has less scope for surprise when calling functions.

Obviously, either behavior would be surprising to different sets of
people, with probably little overlap.  Is one set larger, or has
certain characteristics, like contains more deep thinkers, etc.?

> E.g. I would argue that most people would be surprised, and dismayed, if
> this code fails:
>
> x = 1
> def foo(a, b=x):
>    return a+b
>
> del x
> print foo(2)

Point taken.

> > From your post, it's hard to tell whether this 'duh'-type observation
> > would point out the salient feature of the construct, or whether you're
> > after something deeper.
>
> > If you're asking, 'Why isn't the argument list considered to be inside
> > the body?', then the answer is, it's pretty much arbitrary.
>
> No, it is not an arbitrary choice.

I didn't mean arbitrary as in out-of-the-blue.  I meant arbitrary as
in dart-board decision from hand-picked possibilities, that is, that
the original decision maker thought, 'close call' between two, and
just picked one.

I have a different perspective than he did at the time, and he does
too now.  It's not clear that if he came to think that the cases were
closer than he originally judged, he would say so, though knowing
humans at large, I'd guess that if the case was stronger, he would.  I
would.  Of course not just any human can invent Python.

> I've given practical reasons why the
> Python choice is better. If you want default argument to be created from
> scratch when the function is called, you can get it with little
> inconvenience, but the opposite isn't true. It is very difficult to get
> static default arguments given a hypothetical Python where default
> arguments are created from scratch. There's no simple, easy idiom that
> will work. The best I can come up with is a convention:

I'm not so sure.

## Default evaluated at definition time.  (Current.)

# Static arg.
def f( a= [] ):
  ...

# Non-static arg.
def f( a= None ):
  if a is None: a= []

## Default evaluated at call-time.  (Alternative.)

# Static arg.
@static( a= [] )
def f( a ):
  ...

# Non-static arg.
def f( a= [] ):
  ...

They're about the same difficulty.  This comparison makes it look like
efficiency is the strongest argument-- just an 'if' vs. an entire
extra function call.



More information about the Python-list mailing list