Object containing a list of objects.

C

cocolombo

Hello.

I am putting objects (test) into a container object (tests) and the
test object is also a container for a another list of object
(scores).

Problem is that all instances of class tests have the same value.

To illustrate:

class score(object):
val = 0
def __init__(self, val):
self.val = val
def __str__(self):
return str(self.val) + "\n"

class test(object):
listOfScores = []
def __str__(self):
ret = ""
for s in self.listOfScores:
ret += str(s)
return ret

class tests(object):
listOfTest = []
def __str__(self):
ret = ""
for t in self.listOfTest:
ret += str(t)
return ret


Now I run the script
:
======================
score1 = score(10)
score2 = score(20)
score3 = score(30)
score4 = score(40)

test1 = test()
test2 = test()


test1.listOfScores.append(score1)
test1.listOfScores.append(score2)
test2.listOfScores.append(score3)
test2.listOfScores.append(score4)

theTests = tests()
theTests.listOfTest.append(test1)
theTests.listOfTest.append(test2)

print theTests.listOfTest[0]
print theTests.listOfTest[1]

==============

This is the data structure I am EXPECTING:

theTests
----test1
---score1=10
---score2=20
----test2
---score3=30
---score4=40


But what I get is this:

theTests
----test1
---score1=10
---score2=20
---score3=30
---score4=40
----test2
---score1=10
---score2=20
---score3=30
---score4=40

What is wrong ?

Thanks
 
P

Peter Otten

cocolombo said:
Problem is that all instances of class tests have the same value.

To illustrate:
class tests(object):
listOfTest = []

This makes listOfTest a class attribute. To get one list per instance define
it in the initializer:

class Tests(object):
def __init__(self):
self.tests = []

Peter
 
M

MRAB

Hello.

I am putting objects (test) into a container object (tests) and the
test object is also a container for a another list of object
(scores).

Problem is that all instances of class tests have the same value.

To illustrate:

class score(object):
val = 0
def __init__(self, val):
self.val = val
def __str__(self):
return str(self.val) + "\n"

class test(object):
listOfScores = []
def __str__(self):
ret = ""
for s in self.listOfScores:
ret += str(s)
return ret

class tests(object):
listOfTest = []
def __str__(self):
ret = ""
for t in self.listOfTest:
ret += str(t)
return ret


Now I run the script
:
======================
score1 = score(10)
score2 = score(20)
score3 = score(30)
score4 = score(40)

test1 = test()
test2 = test()


test1.listOfScores.append(score1)
test1.listOfScores.append(score2)
test2.listOfScores.append(score3)
test2.listOfScores.append(score4)

theTests = tests()
theTests.listOfTest.append(test1)
theTests.listOfTest.append(test2)

print theTests.listOfTest[0]
print theTests.listOfTest[1]

==============

This is the data structure I am EXPECTING:

theTests
----test1
---score1=10
---score2=20
----test2
---score3=30
---score4=40


But what I get is this:

theTests
----test1
---score1=10
---score2=20
---score3=30
---score4=40
----test2
---score1=10
---score2=20
---score3=30
---score4=40

What is wrong ?
When you write:

class test(object):
listOfScores = []

you're making 'listOfScores' an attribute of the class.

If you want it to be an attribute of an instance you should write:

class test(object):
def __init__(self):
self.listOfScores = []
 
C

Chris Rebert

Hello.

I am putting objects (test) into a container object (tests) and the
test object is also a container for a another list of object
(scores).

Problem is that all instances of class tests have the same value.

To illustrate:

class score(object):
   val = 0
The previous line does nothing useful; delete it.
   def __init__(self, val):
       self.val = val
   def __str__(self):
       return str(self.val) + "\n"

class test(object):
   listOfScores = []
No! This makes the list a class/static variable *shared between all
instances*. Delete the previous line and define a proper initializer:

def __init__(self):
self.listOfScores = []
   def __str__(self):
       ret = ""
       for s in self.listOfScores:
           ret += str(s)
       return ret

class tests(object):
   listOfTest = []
Again, same problem.

def __init__(self):
self.listOfTest = []
   def __str__(self):
       ret = ""
       for t in self.listOfTest:
           ret += str(t)
       return ret

That is more efficiently+concisely written as:
return "".join(str(t) for t in self.listOfTest)

Now I run the script
:
======================
score1 = score(10)
score2 = score(20)
score3 = score(30)
score4 = score(40)

test1 = test()
test2 = test()


test1.listOfScores.append(score1)
test1.listOfScores.append(score2)
test2.listOfScores.append(score3)
test2.listOfScores.append(score4)

theTests = tests()
theTests.listOfTest.append(test1)
theTests.listOfTest.append(test2)

print theTests.listOfTest[0]
print theTests.listOfTest[1]

==============

This is the data structure I am EXPECTING:
But what I get is this:
What is wrong ?

Python is not Java/C# and has no instance variable declarations. You
just assign to an attribute of self in __init__ and *that* is what
creates instance variables.

Any variables you assign to directly in the class body (as you were
doing with listOfScores and listOfTest) are made class variables (Java
lingo: "static variables"), and are /shared between all instances/,
which is rarely what one actually wants.
To get regular instance variables, define a proper __init__() and
assign the variables to self therein.

Also, per PEP 8 (http://www.python.org/dev/peps/pep-0008/ ):
- Classes are conventionally CapitalizedWords, so name your classes
Score, Test, and Tests rather than score, test, and tests.
- Variables/methods are conventionally underscored_between_words, so
list_of_test rather than listOfTest.

Cheers,
Chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,573
Members
45,046
Latest member
Gavizuho

Latest Threads

Top