Write down this blog, originated from the Tornado Mail Group of this problem how to use outer variable in inner method, the foreigner's answer is very reference value, the key point is basically said. I am here with some interesting examples to do some analysis, a brief description of the Python closure rules, first look at a classic example:
def foo (): a = 1 def bar (): a = a + 1 # Print a + 1 # b = A + 1 # a = 1 print ID (a) bar () print A, ID (a)
Running this function on python2.x will report unboundlocalerror:local variable ' a ' referenced before assignment that is, the local variable is not defined before the reference, how to understand this error? PEP 227 shows that the Python parser is looking for the definition of a variable according to the following level three rules:
The Python 2.0 definition specifies exactly three namespaces to check for each name-the local namespace, the global name Space, and the Builtin namespace.
Here the local may actually have a multi-level, the above code is an example, the following through the code to make some simple changes to understand the law of the surface in one step:
- If a = a + 1 is replaced by print a + 1 or b = A + 1, there is no problem, that is, within the internal function bar, the outer function foo is actually visible, can be referenced.
- It's no problem to change a = a + 1 to a = 1, but if you print out the ID of a in two places, you will find that the two A is not the same, in the inner function bar, the local A = 1 defines a new local variable within the bar function range. Because the name is the same as the variable A in the outer function foo, the A In the outer function foo is actually invisible in the inner function bar.
- Again a = a + 1 error is what happened, first a = xxx This form, the Python parser think to create a new local variable A in the internal function bar, while the external function foo in the bar is no longer visible, and the parser to the right of the next to the A + 1 of the resolution is to use the local variable a plus 1, and then the left of a is a local variable A is not created (and so on the right assignment), so this will produce a chicken eggs or eggs born chicken problem, resulting in the above said Unboundlocalerror error.
To solve this problem, there are two main scenarios in python2.x:
Instead of using aliases such as B = A + 1, the inner function bar only references a in the outer function foo.
Set the A in Foo to a container, such as List
def foo (): a = [1,] def Bar (): a[0] = a[0] + 1 bar () print a[0]
Of course, this is sometimes inconvenient, so in python3.x introduced a nonloacal keyword to solve this problem, as long as a = a + 1 before adding a sentence nonloacal a can, that is, the explicit designation of a is not an intrinsic local variable inside the bar, This allows you to use and re-assign the variable A in the external function foo normally within the bar.
In search of materials related to python closures, I found an interesting question about python closures on StackOverflow, interested in thinking about what to do, and what should be the result? What are your expected results, and if not, what should you do if you want to get the results you expect?
Flist = [] for i in Xrange (3): def func (x): return x * I flist.append (func) for F in Flist:print F (2)