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

Class instance problem?

P: n/a
Hi,

I'm new to python and I've come across a problem with my objects
corrupting each other.

class aclass:
num = 0
l = [[],[]]

a = aclass()
b = aclass()
a.l.append(1)
print "a.l",a.l
print "b.l",b.l

My expectation is that a,b are separate objects, but appending to
a's l also appends to b's l. Why does this occur? On the other hand,
the command

a.num = 1

doesn't change b.num's. This is inconsistency is driving me crazy.
What am I doing wrong?

Thanks for any help
Jul 18 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
In article <c0**************************@posting.google.com >,
zh****@princeton.edu (Zhao Huang) wrote:
I'm new to python and I've come across a problem with my objects
corrupting each other.

class aclass:
num = 0
l = [[],[]]

a = aclass()
b = aclass()
a.l.append(1)
print "a.l",a.l
print "b.l",b.l

My expectation is that a,b are separate objects, but appending to
a's l also appends to b's l. Why does this occur? On the other hand,
the command

a.num = 1

doesn't change b.num's. This is inconsistency is driving me crazy.
What am I doing wrong?


When you set num and l in the class body, you're making them class-wide
variables (like static in Java). If you want a different one per
object, you need to set them in the __init__ method.

--
David Eppstein http://www.ics.uci.edu/~eppstein/
Univ. of California, Irvine, School of Information & Computer Science
Jul 18 '05 #2

P: n/a
On 12 May 2004 21:43:25 -0700, zh****@princeton.edu (Zhao Huang)
declaimed the following in comp.lang.python:
Hi,

I'm new to python and I've come across a problem with my objects
corrupting each other.

class aclass:
num = 0
l = [[],[]]

My expectation is that a,b are separate objects, but appending to
a's l also appends to b's l. Why does this occur? On the other hand,
the command
ONE: read the documentation about mutable and immutable objects.
TWO: num and l are not INSTANCE variables, they are class-wide
definitions. Therefore, ALL instances (objects) created from the class
are using the SAME num and l
a.num = 1

doesn't change b.num's. This is inconsistency is driving me crazy.
Refer back to point "ONE".

Now, to cut to the chase, what you WANT is

class aclass:
def __init__(self):
self.num = 0
self.l = [ [], [] ]

This results in INSTANCE specific variables being created when
the object itself is created:
a = aclass()
b = aclass()
a.l.append([1, 2, 3])
a.num = 4
print a.num 4 print a.l [[], [], [1, 2, 3]] print b.num 0 print b.l [[], []]


-- ================================================== ============ <
wl*****@ix.netcom.com | Wulfraed Dennis Lee Bieber KD6MOG <
wu******@dm.net | Bestiaria Support Staff <
================================================== ============ <
Home Page: <http://www.dm.net/~wulfraed/> <
Overflow Page: <http://wlfraed.home.netcom.com/> <

Jul 18 '05 #3

P: n/a
Hello Zhao,
class aclass:
num = 0
l = [[],[]]

a = aclass()
b = aclass()
a.l.append(1)
print "a.l",a.l
print "b.l",b.l

My expectation is that a,b are separate objects, but appending to
a's l also appends to b's l. Why does this occur? On the other hand,
the command

a.num = 1

doesn't change b.num's. This is inconsistency is driving me crazy.
What am I doing wrong?

Several things :-)
First, "num" and "l" are both *class* properties and not object
properties. The right way to do this is:
class aclass:
def __init__(self):
num = 0
l = [[], []]

Each class method has a `self' parameter which is the object that is
currently called. See the tutorial for more explanation on the subject.

Second "num" and "l" are named bounded to the same objects objects both
in a and b. When you do `a.num =1' you change the binding of a.num to 1.
When you do a.l.append you append to the same objects as in b.l.

HTH.
Miki
Jul 18 '05 #4

P: n/a
Zhao Huang wrote:
Hi,

I'm new to python and I've come across a problem with my objects
corrupting each other.

class aclass:
num = 0
l = [[],[]]
These create class attributes, not instance attributes. For example,
after this you can try:

print aclass.num
print aclass.l

a = aclass()
b = aclass()
a.l.append(1)
Since the instance a does not have an 'l' attribute, a.l refers to the
class attribute aclass.l. You can verify this at this point by:

print a.l is aclass.l # 'is' checks identity of objects

Also you do a.l.append(1). The .append() (note the '.') tells python to
append to the referred object. You are calling a method on the list
object and you end up appending to aclass.l.
print "a.l",a.l
print "b.l",b.l
Also try, print a.l is b.l. There is only one list object, it is on the
class aclass but can be referenced through a.l and b.l.
My expectation is that a,b are separate objects, but appending to
a's l also appends to b's l. Why does this occur? On the other hand,
the command

a.num = 1
Aha, here you use the '=' operator. Compare with operation on the list l
earlier, where you used the '.' operator and a method name 'append'. The
'=' creates an instance attribute 'num' on a.
doesn't change b.num's.
Nope, there is no instance attribute 'num' on b as of now. print b.num
merely prints aclass.num.

Now that you know about '=', you can try

a.L = []
b.L = []
a.L.append(1)
print a.L, b.L

And you'll see that you have two distinct lists. Actually three distinct
ones if you count aclass.l. If you only need instance attributes, don't
put them on the class. Use the following:

class aclass:
def __init__(self):
self.L = []
self.num = 0

a = aclass()
b = aclass()
# play with a.L, b.L, a.num, b.num
This is inconsistency is driving me crazy. What am I doing wrong?

Hope the above helped.

Thanks for any help


--
Shalabh
Jul 18 '05 #5

P: n/a
On Thu, 13 May 2004 08:04:29 +0200, Miki Tebeka wrote:
Hello Zhao,
class aclass:
num = 0
l = [[],[]]

a = aclass()
b = aclass()
a.l.append(1)
print "a.l",a.l
print "b.l",b.l

My expectation is that a,b are separate objects, but appending to
a's l also appends to b's l. Why does this occur? On the other hand,
the command

a.num = 1

doesn't change b.num's. This is inconsistency is driving me crazy.
What am I doing wrong?

Several things :-)
First, "num" and "l" are both *class* properties and not object
properties. The right way to do this is:
class aclass:
def __init__(self):
num = 0
l = [[], []]


You surely intended:

class aclass:
def __init__(self):
self.num = 0
self.l = [[], []]

(for Zhao's mental sanity)

Riccardo

--
-=Riccardo Galli=-

_,e.
s~ ``
~@. ideralis Programs
.. ol
`**~ http://www.sideralis.net
Jul 18 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.