...at least, I think that I'm having a problem understanding the way
closures work.

I'm trying to define a function for an object which will take certain
objects from the parent scope at the time that function is defined.
For some reason, if I do this function definition in a loop, the
locals given by that function (is this a closure?) are changed each
iteration of the loop, whereas if the function definition is isn't
looped over, I get the behavior I desire.  Can anyone provide any
insight for me?

thanks,
-tom!

First, the output:

Test 1 doesn't work the way I would expect:
Test 4 says, "Test 0"
Test 4 says, "Test 1"
Test 4 says, "Test 2"
Test 4 says, "Test 3"
Test 4 says, "Test 4"

...but test 2 does?
Test 0 says, "Test 0"
Test 1 says, "Test 1"
Test 2 says, "Test 2"
Test 3 says, "Test 3"
Test 4 says, "Test 4"

Next, the program:

class Test:
        def __init__(self, name):
                self.name = name
                
        def DoCall(self):
                self.ExternalCall(self.name)
        
# The first test.       
def CreateTests1(count):
        tests = []
        for i in xrange(count):
                name = 'Test %d' % i
                t = Test(name)
                tests.append(t)
                
                def ExCall(text):
                        print '%s says, "%s"' % (name, text)
                        
                t.ExternalCall = ExCall
                
        return tests

# The second test.
def CreateTests2(count):
        tests = []
        for i in xrange(count):
                t = CreateTest(i)
                tests.append(t)
        return tests
                
def CreateTest(index):
        name = 'Test %d' % index
        t = Test(name)
        
        def ExCall(text):
                print '%s says, "%s"' % (name, text)
                
        t.ExternalCall = ExCall
        return t

print 'Test 1 doesn\'t work the way I would expect:'
for t in CreateTests1(5):
        t.DoCall()
        
print '\n...but test 2 does?'
for t in CreateTests2(5):
        t.DoCall()
-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to