Mike Meyer wrote, in part:: > "Gregory Petrosyan" <[EMAIL PROTECTED]> writes: > ... > > 2) Is 'foo.s = n' a correct solution? It seems to be a little more > > elegant. (I tested it, and it worked well) > > It's basically the same solution. You're replacing binding a variable > with mutating an object bound to a name in an outer scope. In one case > the container is named s and is a list that you're setting an element > of. In the other case, the container is named foo and is an object > that you're setting an attribute on.
Well, perhaps the same in the sense of name binding, but there's a subtle difference in replacing the 's = [n]' with 'foo.s = n'. Namely that in the former case (with the essay's original code) a separate container is created when foo() is first called and is what is used in subsequent calls to the function returned. Whereas in the latter case where the foo object itself is used as the container, there's only a single container used by all returned objects -- which would cause problems if you try accumulating two or more different totals simultaneously. Here's a very contrived test case which illustrates the point I'm trying to make: def foo(n): foo.s = n def bar(i): foo.s += i return foo.s return bar a1 = foo(0) a2 = foo(0) print "before a1(0):", a1(0) print "before a2(0):", a2(0) a1(1) a2(1) print "after a1(0):", a1(0) print "after a2(0):", a2(0) >>>> outputs before a1(0): 0 before a2(0): 0 after a1(0): 2 after a2(0): 2 Notice that it even though each was only incremented by 1 once, they interacted, and show the effects of two calls. This doesn't happen in in Paul Graham's version, where the two 'after' calls would correctly retrun a value of 1. -Martin -- http://mail.python.org/mailman/listinfo/python-list