473,325 Members | 2,671 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,325 software developers and data experts.

Bug in __init__?

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@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
Jan 18 '08 #1
10 1014
Zbigniew Braniecki wrote:
Any clue on what's going on here, and/if where I should report it?
Congratulations! You've stumbled over a well known gotcha. Most newbies
fall for the trap.

class A:
def __init__ (self, val=[]):
print val
self.lst = val

val is created only *once* and shared across all instaces of A.

Christian

Jan 18 '08 #2
On Jan 18, 2008 3:09 PM, Zbigniew Braniecki
<zb****************@gmail.comwrote:
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@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?
It is a FAQ, not a bug:
http://www.python.org/doc/faq/genera...etween-objects
http://effbot.org/pyfaq/why-are-defa...en-objects.htm

--
http://www.advogato.org/person/eopadoan/
Bookmarks: http://del.icio.us/edcrypt
Jan 18 '08 #3
On Jan 18, 9:09 am, Zbigniew Braniecki <zbigniew.branie...@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@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
Jan 18 '08 #4
"Zbigniew Braniecki" schrieb
I found a bug in my code today, and spent an hour trying to locate
it
and then minimize the testcase.
[...]
def __init__ (self, val=[]):
[...]
Any clue on what's going on here, and/if where I should report it?
I think this has to do with
http://docs.python.org/tut/node6.htm...00000000000000
especially the "Important Warning"

Regards
Martin

Jan 18 '08 #5
Christian Heimes wrote:
Zbigniew Braniecki wrote:
>Any clue on what's going on here, and/if where I should report it?

Congratulations! You've stumbled over a well known gotcha. Most newbies
fall for the trap.

class A:
def __init__ (self, val=[]):
print val
self.lst = val

val is created only *once* and shared across all instaces of A.
Thanks for help guys!

It's really a nice pitfall, I can hardly imagine anyone expecting this,
or how easily could I find this info (e.g. what query should I give to
google to get it without bothering people on this group)

Anyway, thanks :)

Greetings
Zbigniew Braniecki
Jan 18 '08 #6
On Jan 18, 2008 12:33 PM, Zbigniew Braniecki
<zb****************@gmail.comwrote:
class A:
def __init__ (self, val=[]):
print val
self.lst = val

val is created only *once* and shared across all instaces of A.

Thanks for help guys!

It's really a nice pitfall, I can hardly imagine anyone expecting this,
or how easily could I find this info (e.g. what query should I give to
google to get it without bothering people on this group)
In this unfortunate case, useful searches were "default arguments",
which would be hard to guess without already knowing what's going
wrong, or "python gotchas pitfalls", which is a good general purpose
search for when you can't understand what's happening in simple code.

--
Neil Cerutti <mr***************@gmail.com>
Jan 18 '08 #7
On 2008-01-18, citizen Zbigniew Braniecki testified:
It's really a nice pitfall, I can hardly imagine anyone expecting this,
AFAIR, it's described in Diving Into Python.
It's quiet elegant way of creating cache.

def calculate(x,_cache={}):
try:
return _cache[x]
except KeyError:
_cache[x] = result = _lotsa_slow_calculations(x)
return result

bart
--
This signature is intentionally left blank.
http://candajon.azorragarse.info/ http://azorragarse.candajon.info/
Jan 20 '08 #8
On Jan 20, 3:39*pm, Bart Ogryczak <B.Ogryc...@addr.in.reply-
to.invalidwrote:
On 2008-01-18, citizen Zbigniew Braniecki testified:
It's really a nice pitfall, I can hardly imagine anyone expecting this,

AFAIR, it's described in Diving Into Python.
Still there seems to be about one message a week about this. Indeed I
reckon the greatest benefit of early binding of default function
arguments is that it attracts lots of new people to comp.lang.python.
It's quiet elegant way of creating cache.
IMHO, calling it 'elegant' is pushing it too far!

--
Arnaud

Jan 20 '08 #9
Is there no way of adding a possible warning message (that obviously
could be turned off) to warn users of possible problems linked to
using mutable types as parameters?

Seems to me this could save users a few minutes/hours of headaches and
headscratching. (The biggest issue affecting new programmers these
days!)
Jan 21 '08 #10
On 2008-01-22, citizen Bruno Desthuilliers testified:
> from copy import copy
### see also deepcopy
self.lst = copy(val)

What makes you think the OP wants a copy ?
I´m guessing he doesn´t want to mutate original list, while changing
contents of self.lst.

bart
--
"chłopcy dali z siebie wszystko, z czego tv pokazała głównie bebechy"
http://candajon.azorragarse.info/ http://azorragarse.candajon.info/
Jan 22 '08 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Jim Jewett | last post by:
Normally, I expect a subclass to act in a manner consistent with its Base classes. In particular, I don't expect to *lose* any functionality, unless that was the whole point of the subclass. ...
4
by: Martin Maney | last post by:
I've been to the cookbook (both forms, since they're sometimes usefully different), but that gave rise to more questions than answers. Heck, let me pull some of them up while I'm at it. ...
6
by: Steven Bethard | last post by:
So when I'm writing a class and I define an __init__ method, I sometimes haven't called object.__init__, e.g.: class C(object): def __init__(self, x): self.x = x instead of class...
14
by: Axel Straschil | last post by:
Hello! Im working with new (object) classes and normaly call init of ther motherclass with callin super(...), workes fine. No, I've got a case with multiple inherance and want to ask if this...
7
by: Kent Johnson | last post by:
Are there any best practice guidelines for when to use super(Class, self).__init__() vs Base.__init__(self) to call a base class __init__()? The super() method only works correctly in multiple...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.