Object containing a list of objects.

2010-08-28 Thread 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
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Object containing a list of objects.

2010-08-28 Thread MRAB

On 28/08/2010 18:48, cocolombo wrote:

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 = []
--
http://mail.python.org/mailman/listinfo/python-list


Re: Object containing a list of objects.

2010-08-28 Thread Peter Otten
cocolombo wrote:

 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
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Object containing a list of objects.

2010-08-28 Thread Chris Rebert
On Sat, Aug 28, 2010 at 10:48 AM, cocolombo cocolo...@gmail.com wrote:
 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:
snip
 But what I get is this:
snip
 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
--
http://blog.rebertia.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Object containing a list of objects.

2010-08-28 Thread cocolombo
Thanks MRAB and Peter Otten that solved the problem.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Object containing a list of objects.

2010-08-28 Thread cocolombo
Chris I take good notice of your comments and suggestions. Thanks.
-- 
http://mail.python.org/mailman/listinfo/python-list