By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
444,089 Members | 2,260 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 444,089 IT Pros & Developers. It's quick & easy.

Basic Class/Instance Question

P: n/a
Ready to go insane here. Class A, taking on a default value for a
variable. Instantiating two separate objects of A() gives me a shared
val list object. Just see the example bellow:
class A(object):
def __init__(self, val=[]):
self.val=val

obj1 = A()
obj2 = A()

print obj1 is obj2 # False - as expected
print obj1.val is obj2.val # True! - Why... oh god WHY
-----------
Using python 2.4. Is this a bug with this version of python? How can I
trust the rest of the universe is still in place? Could she still like
me? Many questions I have. Lets start with the python problem for now.

Thanks,
Sia

May 23 '07 #1
Share this Question
Share on Google+
5 Replies


P: n/a
Il 23 May 2007 04:07:19 -0700, Siah ha scritto:
Ready to go insane here. Class A, taking on a default value for a
__init__ is a function, taking a default value of [], which is a list,
which is a mutable object. That said, you should remember that this means
that such default value is 'shared' between all instances. If you don't
want that, do something like:

def __init__(self, defaultvalue=None):
if defaultvalue is None:
defaultvalue=[]

http://docs.python.org/tut/node6.htm...00000000000000
--
Alan Franzoni <al***************@gmail.com>
-
Togli .xyz dalla mia email per contattarmi.
Remove .xyz from my address in order to contact me.
-
GPG Key Fingerprint (Key ID = FE068F3E):
5C77 9DC3 BD5B 3A28 E7BC 921A 0255 42AA FE06 8F3E
May 23 '07 #2

P: n/a
Siah a écrit :
Ready to go insane here. Class A, taking on a default value for a
variable. Instantiating two separate objects of A() gives me a shared
val list object. Just see the example bellow:
class A(object):
def __init__(self, val=[]):
self.val=val

obj1 = A()
obj2 = A()

print obj1 is obj2 # False - as expected
print obj1.val is obj2.val # True! - Why... oh god WHY
-----------
Using python 2.4. Is this a bug with this version of python? How can I
trust the rest of the universe is still in place? Could she still like
me? Many questions I have. Lets start with the python problem for now.
This is a FAQ. Default arguments are only evaled once - when the def
statement is evaled (which is usually at import time). The solution is
simple: don't use mutable objects as default arguments:

class A(object):
def __init__(self, val=None):
if val is None:
val = []
self.val=val

FWIW, do you really believe such a 'bug' would have stayed unnoticed ?-)

Else, the rest of the universe seems to be in place, and I don't know if
she'll still like you if she learn you didn't read the FAQ before
posting !-)

HTH
May 23 '07 #3

P: n/a
On 2007-05-23, Bruno Desthuilliers <br********************@wtf.websiteburo.oops.comwr ote:
Siah a écrit :
>Ready to go insane here. Class A, taking on a default value for a
variable. Instantiating two separate objects of A() gives me a shared
val list object. Just see the example bellow:
class A(object):
def __init__(self, val=[]):
self.val=val

obj1 = A()
obj2 = A()

print obj1 is obj2 # False - as expected
print obj1.val is obj2.val # True! - Why... oh god WHY


-----------
Using python 2.4. Is this a bug with this version of python? How can I
trust the rest of the universe is still in place? Could she still like
me? Many questions I have. Lets start with the python problem for now.

This is a FAQ. Default arguments are only evaled once - when the def
statement is evaled (which is usually at import time). The solution is
simple: don't use mutable objects as default arguments:
An immutable object would have given the same behaviour in this case

class A(object):
def __init__(self, val = ()):
self.val=val

obj1 = A()
obj2 = A()

print obj1 is obj2 # False
print obj1.val is obj2.val # True

May 23 '07 #4

P: n/a
Antoon Pardon wrote:
>This is a FAQ. Default arguments are only evaled once - when the def
statement is evaled (which is usually at import time). The solution is
simple: don't use mutable objects as default arguments:

An immutable object would have given the same behaviour in this case

class A(object):
def __init__(self, val = ()):
self.val=val

obj1 = A()
obj2 = A()

print obj1 is obj2 # False
print obj1.val is obj2.val # True

Yeah, but is that a problem? Since you can not change them anyway,
there's no harm.
W

May 23 '07 #5

P: n/a
On 2007-05-23, Wildemar Wildenburger <wi******@freakmail.dewrote:
Antoon Pardon wrote:
>>This is a FAQ. Default arguments are only evaled once - when the def
statement is evaled (which is usually at import time). The solution is
simple: don't use mutable objects as default arguments:

An immutable object would have given the same behaviour in this case

class A(object):
def __init__(self, val = ()):
self.val=val

obj1 = A()
obj2 = A()

print obj1 is obj2 # False
print obj1.val is obj2.val # True

Yeah, but is that a problem? Since you can not change them anyway,
there's no harm.
I think it can make comprehension harder if you suggest in your
explanation that a partcilular behaviour is linked to an object
being mutable while that has nothing to do with it.

You are correct that one can't mutate the val attribute but
some code might depend on the distinction identical or not
instead of equal or not. Not understanding this issue of
default arguments could cause a bug in such code even
if the default argument is not mutable.

--
Antoon Pardon
May 24 '07 #6

This discussion thread is closed

Replies have been disabled for this discussion.