I don't think Dennis or Steven read your post very well.
It's possible.
You said 'Why
does Python do X?', and 'It seems natural to you to do not X'. Dennis
and Steven both said, 'Python does X'.
I also disputed that it is natural to do not-X (runtime creation of
default arguments), and explained why such an interpretation doesn't
match with the way Python operates. I admit I didn't answer the "why"
part.
Steven did get around to suggesting an answer though. He said:
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
Taking this to be true, the answer to your question is, 'Because the
object isn't created inside the body of the function,' or, 'Because the
argument list is outside the body of the function'.
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.
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.
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)
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'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:
# Please don't change this, or strange things will happen.
_private = ResultOfExpensiveCalculation()
def foo(a, b=_private):
return a+b
The above is still vulnerable to code accidentally over-writing _private
with some other value, or deleting it, but at least we avoid the
expensive calculation every time.
Or possibly:
def foo(a, b=foo._private):
return a+b
foo._private = ResultOfExpensiveCalculation()
which has obvious disadvantages with regard to shadowing, renaming,
anonymous functions, and so forth.
Regardless
of which one the author of Python chose, the other's workaround would be
equally short,
Not true. One has an obvious workaround, the other only has a *partial*
workaround.
and neither one is obviously indicated by the syntax.
I would disagree, but not enough to argue.