On Mon, Jul 27, 2009 at 1:40 PM, Reckoner<recko...@gmail.com> wrote: > Hi, > > Observe the following: > > In [202]: class Foo(): > .....: def __init__(self,h=[]): > .....: self.h=h > .....: > .....: > > In [203]: f=Foo() > > In [204]: g=Foo() > > In [205]: g.h > Out[205]: [] > > In [206]: f.h > Out[206]: [] > > 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 am I missing here? > > I'm using Python 2.5.1. > > Thanks in advance.
. It has to do with the way Python handles functions and class methods. Basically, when the parser creates the class Foo, it also creates all of Foo's class variables and functions. It's at this point, and only at this point, that the default parameter is evaluated. When you make an instance of Foo, just wraps the function __init__ by filling in the initial parameter. Because both f and g are really using the Foo.__init__ function (as opposed to separate f.__init__ and g.__init__ methods), they share the same default parameter, a list that was created at the very beginning. Since f.h and g.h both refer to the same list, updating f.h will also update g.h (and the default parameter). That's why it's a bad idea to use mutable default parameters- use either None class Foo(object) : def __init__(self, h=None) : if h is None: h = [] or, if None is an acceptable value, make a sentinel value sentinel = object() class Foo(object) : def __init__(self, h = sentinel) : if h is sentinel: h = [] > -- > http://mail.python.org/mailman/listinfo/python-list > -- http://mail.python.org/mailman/listinfo/python-list