[Tutor] Python function seem to have a memory ???

Kalle Svensson kalle@gnupung.net
Sat, 11 Aug 2001 15:23:08 +0200


[Simon Vandemoortele]
> 
> I am making my first contact with python through the means of the tutorial
> (http://www.python.org/doc/current/tut/) and I would like some clarification 
> on the example:
> 
> --- quote ---
> Important warning: The default value is evaluated only once. This makes a 
> difference when the default is a mutable object such as a list or dictionary. 
> 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]
> --- end quote ---
> 
> One thing I find astonishing about this is the fact that python functions 
> seem to have memory; each call of f() leads to a different result ! Does this 
> mean that the variable 'l' keeps its content even after the function returns 
> ? This seems very strange to me as I have never seen it in other languages. 

This can indeed seem a little weird.  The important thing to remember here
is that 'l = []' is executed once, when the def statement is executed[1].
With immutable objects, this won't make any difference, as any operations on
the object will result in a new object.  Mutable objects, though, can be
changed.  As the default argument is the same every time the function is
called, we see the "memory" effect.

You may also notice that

def g():
    return []

def f(a, l = g()):
    l.append(a)
    return l

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

works, but

def f(a, l = g()):
    l.append(a)
    return l

def g():
    return []

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

doesn't.  Confused?  Good. <wink>

Peace,
  Kalle

[1]  This is how it looks throught the dis module:

def f(a, l):
    l.append(a)
    return l

becomes:

3 SET_LINENO       3
6 LOAD_CONST       0 (<code object f at 0x8118500, file "test.py", line 3>)
9 MAKE_FUNCTION    0
12 STORE_NAME      0 (f)

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

becomes:

15 SET_LINENO      7
18 BUILD_LIST      0  # <----------------  This is it...
21 LOAD_CONST      1 (<code object f at 0x8184590, file "test.py", line 7>)
24 MAKE_FUNCTION   1
27 STORE_NAME      0 (f)
-- 
[  kalle@gnupung.net  ][ Thought control, brought to you by the WIPO! ]
[ http://gnupung.net/ ][ http://anti-dmca.org/ http://eurorights.org/ ]