Once-only evaluation of default parameter values function definitions

Fred Ma fma at doe.carleton.ca
Tue Apr 13 01:25:50 EDT 2004


Hello,

I'm looking at Python for the 1st time today, motivated by its clarity
of syntax.  I've looked at the tutoarial at
http://www.python.org/doc/current/tut/tut.html, particularly at the
section about default arguments.  I've got some C++/STL under my belt,
so I'm familiar with passing/returning by reference, by value, and by
pointers.  I've also used containers of pointers, as well as c++
default parameter values.  I am aware of the general idea of reference
counting, but have never used it.

>From the python tutorial, it's clear that to avoid sharing default
values between function calls, one has to avoid:

   Example#1
   ---------
   def f(a, L=[]):
       L.append(a)
       return L

Instead, one should use:

   Example#2
   ---------
   def f(a, L=None):
       if L is None:
           L = []
       L.append(a)
       return L

None has been described a analogous to the NULL value in c++.  I'm
been looking and googling this newsgroup to get a clearer explanation
of why this works.  The tutorial says that the default value is only
evaluated once.  By that, I assume that there is some unnamed object
that is given the value of the 1st and only evaluation of the default
expression.  Every time the function is called without an L parameter,
L gets the value of this unnamed object.  But that is not consistent
with the Example#1 i.e.

   print f(1)
   print f(2)
   print f(3)

prints

   [1]
   [1, 2]
   [1, 2, 3]

The unnamed object that I imagined should have the value [], and L
should get set to [] every time that f() is called without a value
specified for L.

The alternative explanation that I could think of is that L is bound
to the unnamed object [], and the object itself changes values to
reflect changes to L i.e. L is now a persistent variable, retaining
its value between function calls unless a value is provided for L in
the function call's argument list.  In the latter case, one can
imagine L simply being overwritten with the value provided.

The problem with this picture is that Example#2 should fail for the
same reasons as Example#1.  That is, L will not get the value of None
on the 2nd call to f() without a value specified for L.  Hence, L will
not be reset to [].

I searched through the tutorials for programmers.  The same idiom is
presented, but I can't seem to find a more detailed explanation.  Some
threads here presented None as something that gets treated differently
from a value, so I confirmed from the language reference that None is
not just a value, but its own type.  The thread "Default Parameters to
function!" quotes the language reference in saying that the object
that L is bound to actually gets changed, when the function body makes
changes to the variable L.  Again, if this was the case, it seems like
that should cause Example#2 to fail as well (obviously something I'm
missing here).

I'd appreciate it if someone could provide an explanation that's
suitable for my background (some C++ experience, but not a
practitioner of the more advanced concepts).  Thanks.

Fred



More information about the Python-list mailing list