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?
相关问题
- how to define constructor for Python's new Nam
- streaming md5sum of contents of a large remote tar
- How to get the background from multiple images by
- Evil ctypes hack in python
- Correctly parse PDF paragraphs with Python
There is a wart in python's scoping rules - assignment makes a variable local to its immediately enclosing function scope. For a global variable, you would solve this with the
global
keyword.The solution is to introduce an object which is shared between the two scopes, which contains mutable variables, but is itself referenced through a variable which is not assigned.
An alternative is some scopes hackery:
You might be able to figure out some trickery to get the name of the parameter to
outer
, and then pass it as varname, but without relying on the nameouter
you would like need to use a Y combinator.Extending Martineau elegant solution above to a practical and somewhat less elegant use case I get:
Here's something inspired by a suggestion Alois Mahdal made in a comment regarding another answer:
Update
After looking back at this recently, I was struck by how decorator-like it was—and then it dawned on my that it could formally be turned into one which would make it more generic & useful (although doing so degrades its readability somewhat).
Also note that the code in both versions will still work in Python 3.x.
Another way to do it (although it's too verbose):
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.,
should work as expected (printing 3). However, overriding the value of x does not work, e.g.,
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):
Inner functions can read nonlocal variables in 2.x, just not rebind them. This is annoying, but you can work around it. Just create a dictionary, and store your data as elements therein. Inner functions are not prohibited from mutating the objects that nonlocal variables refer to.
To use the example from Wikipedia: