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