[Tutor] python's default argument value handling in functions - weird syntax? problem grappling with the concept

Jeffrey Lim jfs.world at gmail.com
Wed Feb 9 21:14:05 CET 2005


hey folks, i'm a relative newbie to python itself, and I am currently
learning by making my way through the tutorial found within the docs
of 2.4 (http://www.python.org/doc/2.4/tut/tut.html).

I am currently having a problem dealing with the concept of the
"default argument value" in python functions, and just how python
handles this.

Now http://www.python.org/doc/2.4/tut/node6.html#SECTION006710000000000000000
makes the statement that "the default value is evaluated only once".
While that is fine, what I don't really get is how the solution given
can even make sense - either syntactically, or conceptually.

First of all, let me quote what the doc says:

===========
Important warning: The default value is evaluated only once. This
makes a difference when the default is a mutable object such as a
list, dictionary, or instances of most classes. For example, the
following function accumulates the arguments passed to it on
subsequent calls:

def f(a, L=[]):
    L.append(a)
    return L

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

This will print

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

If you don't want the default to be shared between subsequent calls,
you can write the function like this instead:

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

This leads me to at first conclude several things:

1. 'L' in this case (or by extension, all function arguments for which
a default is given in the function definition) is "static" (see 'C'
language definition). This is my conclusion, seeing as how 'L' can
seem to retain its value even though it has gone out of scope after
the 'f' function returns.

Correct me if i'm wrong here, guys.

2. (*Now this is where I start to get confused. I think the best way
to illustrate how I am having problems is to illustrate with a few
examples. The basic problem that I am having is, "Which L is which
L?")

My examples...

Example 1
>>> def f(a,L=[]):
...     if L==[5]:
...       print 'L==[5] caught'
...       print L
...       print 'resetting L...'
...       L=[]
...     L.append(a)
...     return L
...
>>> f(5)
[5]
>>> f(5)
L==[5] caught
[5]
resetting L...
[5]
>>> f(2)
L==[5] caught
[5]
resetting L...
[2]


Example 2
>>> def f(a,L=None):
...     if L==[5]:
...             print 'caught, printing, resetting'
...             print L
...             L=[]
...     else:
...             L=[]
...     L.append(a)
...     return L
...
>>> f(5)
[5]
>>> f(6)
[6]
>>> f(6)


So when the default value for 'L' is an empty list, the test
condition, _once triggered_, *always* catches?

But when the default value for 'L' is none, the 'if' never catches?

How is this possible?

Or even consider the example given -
def f(a, L=None):
    if L is None:
        L = []
    L.append(a)
    return L

How is 'L == None' even possible all the time, given that for
def f(a, L=[]):
    L.append(a)
    return L
, L isn't even [] except for the first call to 'f'?


-jf


More information about the Tutor mailing list