I'm trying to implement a closure in Python 2.6 and I need to access a nonlocal variable but it seems like this keyword is not available in python 2.x. How should one access nonlocal variables in closures in these versions of python?
A:
you can pass on the value, if you don't intend to modify it.
if you want to use nonlocal x
, use:
def inner(a, b, .., x=x):
# ...
mykhal
2010-07-06 22:49:29
You won't be changing the value of x in the outer scope. When you use nonlocal in python 3 you can change the value of x. Read the final example in this section of the faq: http://docs.python.org/py3k/faq/programming.html?why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value#why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value
PreludeAndFugue
2010-07-06 22:54:33
@PreludeAndFugue you're right. my "fake" solution only provides read-only access of the non-local variable. however, it might be sufficient fo some uses. *edited the answer*
mykhal
2010-07-06 22:59:06
+2
A:
Python can read nonlocal variables in 2.x, just not change them. This is annoying, but you can work around it. Just declare a dictionary, and store your variables as elements therein.
To use the example from Wikipedia:
def outer():
d = {'y' : 0}
def inner():
d['y'] += 1
return d['y']
return inner
f = outer()
print(f(), f(), f()) #prints 1 2 3
Chris B.
2010-07-06 22:50:58
A:
I think the key here is what you mean by "access". There should be no issue with reading a variable outside of the closure scope, e.g.,
x = 3
def outer():
def inner():
print x
inner()
outer()
should work as expected (printing 3). However, overriding the value of x does not work, e.g.,
x = 3
def outer():
def inner():
x = 5
inner()
outer()
print x
will still print 3. From my understanding of PEP-3104 this is what the nonlocal keyword is meant to cover. As mentioned in the PEP, you can use a class to accomplish the same thing (kind of messy):
class Namespace(object): pass
ns = Namespace()
ns.x = 3
def outer():
def inner():
ns.x = 5
inner()
outer()
print ns.x
ig0774
2010-07-06 22:51:19