Quoting Reckoner <recko...@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 -- http://mail.python.org/mailman/listinfo/python-list