initializing with empty list as default causes freaky problems

Luis Alberto Zarrabeitia Gomez kyrie at uh.cu
Mon Jul 27 14:25:47 EDT 2009



Quoting Reckoner <reckoner at gmail.com>:

> Hi,
> 
> Observe the following:
> 
> In [202]: class Foo():
>    .....:     def __init__(self,h=[]):
>    .....:         self.h=h
[...]
> In [207]: f.h.append(10)
> 
> In [208]: f.h
> Out[208]: [10]
> 
> In [209]: g.h
> Out[209]: [10]
> 
> The question is: why is g.h updated when I append to f.h?  Shouldn't
> g.h stay []?

What you are seeing is basically the same that happens here: 

===
In [1]: def f(l=[]):
   ...:     l.append(1)
   ...:     print l
   ...: 

In [2]: f()
[1]

In [3]: f()
[1, 1]

In [4]: f()
[1, 1, 1]
===

The problem is that the default value "[]" is evaluated only once, at function
creation time, and not at invocation. Thus, every call to the function shares
the same default object. That is consistent with python's function type: the
"def" construct just creates a function object and initializes it with the code,
argument list and default values. That means that the default value are part of
the function object itself, regardless of when/if it is called:

===
In [5]: f.func_defaults
Out[5]: ([1, 1, 1],)
===

The recommended way of dealing with this case (mutable default arguments) is:

def f(l = None):
    if l is None:
        l = []
    # the code goes here.

(in your case, your g.__init__ and f.__init__ methods share the same
Foo.__init__ function, and thus, share the same default value [])

That is a very common python gotcha, and I think it is well documented in the
standard doc (but I can't find it right now, sorry). Unfortunately, it doesn't
become intuitive until you've spent a while understanding python's execution
model (and then you suddenly realize that it just makes sense).

[And now I wonder... how other languages do it? I've spent so much time with
python that reevaluating the default argument on invocation feels clumsy, but
I'm obviously tainted now...]

Regards,

-- 
Luis Zarrabeitia
Facultad de Matemática y Computación, UH
http://profesores.matcom.uh.cu/~kyrie



-- 
Participe en Universidad 2010, del 8 al 12 de febrero de 2010
La Habana, Cuba 
http://www.universidad2010.cu




More information about the Python-list mailing list