Notes for using closures in Python Programming
This article mainly introduces some notes for using closures in Python programming. The article is from the blog of felden, a well-known Python developer in China. For more information, see
I wrote this blog, which originated from the Tornado contact group question. how to use outer variable in inner method is of great reference value to the answers from foreigners. The key points are basically described. Here I will use some interesting examples to do some parsing and briefly describe the closure rules of Python. First, let's look at a classic example:
?
1 2 3 4 5 6 7 8 9 10 11 |
Def foo (): A = 1 Def bar (): A = a + 1 # Print a + 1 # B = a + 1 # A = 1 Print id () Bar () Print a, id () |
Running this function on Python2.x will report UnboundLocalError: local variable 'A' referenced before assignment, that is, the local variable is not defined before reference. How can we understand this error? As described in PEP 227, the Python parser searches for a variable definition according to the following three-level rules:
The Python 2.0 definition specifies exactly three namespaces to check for each name-the local namespace, the global namespace, and the builtin namespace.
The local here may actually have multiple levels. The above code is an example. Below we will make some simple modifications to the Code to understand the rules below step by step:
If you replace a = a + 1 with print a + 1 or B = a + 1, there is no problem, that is, in the internal function bar, the a in the external function foo is actually visible and can be referenced.
Changing a = a + 1 to a = 1 is no problem, but if you print the id of a in the two places, you will find that these two a are not the same thing, in the internal function bar, local a = 1 defines a new local variable within the bar function range, because the name is the same as the name of variable a in the external function foo, as a result, a in the external function foo is invisible in the internal function bar.
Next, let's look at what is wrong with a = a + 1. First, in the form of a = xxx, the Python parser considers that a new local variable a should be created in the internal function bar, at the same time, the in the external function foo is invisible in bar, And the parser parses the next a + 1 on the right to add 1 to the local variable, at this time, the local variable a on the left has not been created (such as the assignment on the right). Therefore, this produces a question about whether it is a chicken or an egg, this causes the UnboundLocalError mentioned above.
To solve this problem, there are two main solutions in Python2.x:
Replace B with an alias, for example, B = a + 1. The internal function bar only references a in the external function foo.
Set a in foo to a container, such as list
?
1 2 3 4 5 6 7 |
Def foo (): A = [1,] Def bar (): A [0] = a [0] + 1 Bar () Print a [0] |
Of course, this is inconvenient sometimes. Therefore, a nonloacal keyword is introduced in Python3.x to solve this problem. You only need to add a nonloacal a before a = a + 1, explicitly specifying a is not a local variable in the internal function bar, so that you can use it normally in the bar and assign a value to variable a in the external function foo.
In the search for Python closure-related materials, I found an interesting question about Python closure on StackOverflow. If you are interested, you can think about it. What is the result? What are your expected results? If they are inconsistent, how should you change the expected results?
?
1 2 3 4 5 6 7 8 |
Flist = [] For I in xrange (3 ): Def func (x): return x * I Flist. append (func) For f in flist: Print f (2) |
Note <>: For more exciting tutorials, please pay attention to the help house programming