Bug in __init__?

Matimus mccredie at gmail.com
Fri Jan 18 12:22:35 EST 2008


On Jan 18, 9:09 am, Zbigniew Braniecki <zbigniew.branie... at gmail.com>
wrote:
> I found a bug in my code today, and spent an hour trying to locate it
> and then minimize the testcase.
>
> Once I did it, I'm still confused about the behavior and I could not
> find any reference to this behavior in docs.
>
> testcase:
>
> class A():
>
>    def add (self, el):
>      self.lst.extend(el)
>
>    def __init__ (self, val=[]):
>      print val
>      self.lst = val
>
> def test ():
>    x = A()
>    x.add(["foo1","foo2"])
>    b = A()
>
> So, what I would expect here is that I will create two instances of
> class A with empty self.lst property. Right?
>
> In fact (at least with my Python 2.5)
>
> gandalf at gandalf-desktop:~/projects/pyl10n$ ./scripts/test.py
> []
> ['foo1', 'foo2']
>
> This bug does not happen when I switch to __init__ (self, *args) and
> assign self.lst= args[0].
>
> Any clue on what's going on here, and/if where I should report it?
>
> Greetings
> Zbigniew Braniecki

Look at item number 5. http://zephyrfalcon.org/labs/python_pitfalls.html

People run into this quite often. Basicly, you created a list as a
default argument. This doesn't create a new empty list ever time
__init__ is called. Everyone is getting the same list. How to get
around this:

class A(object): # derive from object for new-style classes
   def add (self, el):
     self.lst.extend(el)

   def __init__ (self, val=None): # Use None instead
     if val is None:
         val = [] # create a new list if needed each time
     print val
     self.lst = val


HTH

Matt



More information about the Python-list mailing list