[Tutor] default argument frustration

Kent Johnson kent37 at tds.net
Fri Feb 11 14:04:20 CET 2005


Brian van den Broek wrote:
> At first, I ended up with every single node being a copy of the first 
> one processed. A bit of weeping later, I realized that this is from the 
> feature [?] of Python that default arguments are evaluated just once. 
> (Note the comment added above.)
> 
> <venting>
> FOR THE LOVE OF MIKE can someone tell me even one reason why this isn't 
> a misfeature?!?!
> </venting>

I will guess...because historically it was useful, and because the alternative is problematic.

Before Python 2.1, when nested scopes were introduced, default arguments were widely used as a way
to bind values from the local environment into a function.

For example, suppose I want to write a function of one argument that returns a function of one
argument that adds the two arguments together. Today, I can write
  >>> def makeAdder(n):
  ...   def f(x):
  ...     return x+n
  ...   return f
  ...
  >>> add5 = makeAdder(5)
  >>> add5(2)
7

In Python 2.0 this doesn't work, add5 will not know the value of n.

The common workaround was to provide n as a default argument to f:

  >>> def makeAdder2(n):
  ...   def f(x, n=n):
  ...     return x+n
  ...   return f

Now n is bound as a default argument when f is created, and makeAdder2() works the same as makeAdder().

OK, now imagine what would happen to makeAdder2() if the default argument was evaluated at the point 
of call? It would use whatever value of n was in scope at the time. This could be confusing - n 
might well not even be defined!

What this really does is make variables in default arguments be dynamically scoped. Since other 
variables in Python are lexically scoped, this would be kind of strange.
http://en.wikipedia.org/wiki/Dynamic_scoping
http://en.wikipedia.org/wiki/Lexical_variable_scoping

Kent



More information about the Tutor mailing list