0

I've encountered a behavior in a Python program that I've been able to condense into a smaller program. I'm pretty sure I've encountered it and solved it and the past, but can't remember how.

Consider the following Python program:

import random

class B:
    def __init__(self):
        self.attr=random.randrange(0,10)

class A:
    def __init__(self):
        self.b=B()

list=[]
print "First pass"
for i in range(0,10):
    a=A()
    print "Random number in b: ",a.b.attr
    list.insert(0,a)

print "Second pass"
for l in list:
    print "Random number in b: ",a.b.attr

It typically outputs something such as:

First pass
Random number in b:  9
Random number in b:  7
Random number in b:  1
Random number in b:  5
Random number in b:  9
Random number in b:  7
Random number in b:  0
Random number in b:  6
Random number in b:  2
Random number in b:  7

Second pass
Random number in b:  7
Random number in b:  7
Random number in b:  7
Random number in b:  7
Random number in b:  7
Random number in b:  7
Random number in b:  7
Random number in b:  7
Random number in b:  7
Random number in b:  7

How do we solve this? I know it has to do with how Python copies object etc., but having:

import copy
list.insert(0,copy.deepcopy(a))

Doesn't solve it as one could expect.

1
  • Uh, in your second pass, you are displaying a.b.attr instead of l.b.attr. a is left over from the first pass loop, so you are seeing the constant output. Commented Dec 13, 2012 at 6:13

1 Answer 1

1

Maybe instead of

print "Second pass"
for l in list:
    print "Random number in b: ",a.b.attr

Use

print "Second pass"
for l in list:
    print "Random number in b: ", l.b.attr
Sign up to request clarification or add additional context in comments.

3 Comments

I am an idiot. This solves my question, although I still have a similar issue; now to write a proper test program that reproduces the bug I'm experiencing.
Here's a basic test program that expresses the gist of the problem I was having: pastebin.com/MQMKpNhh - I've figured it though (for those stumbling on this: it's because values is initiated with an empty dict, which is mutable; you want your construction vars to be initiated with immutable values)
Glad you figured it out! Actually not "because values is initiated with an empty dict", but because you made values a class attribute, instead of creating it per instance inside __init__

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.