According to common interview questions to talk about Python Python closures

Here, according to some Python often and we usually see questions with you to talk about issues related to Python on closures!

topic:

1. What is a closure? Closed-defined package?

2. Handwritten a simple closure

3. variable scoping rules with nonlocal keyword?

4. Application of closure

According to common interview questions to talk about Python Python closures

 

The answer points:

1. First, we need to understand variable scope

Example # a 
DEF test1 (A):
Print (A)
Print (B) when the function # which can perform a given step time.
# NameError: Global name 'B' IS Not defined
test1 (. 1)
# exemplary two
B =. 6
DEF test2 (A):
Print (A)
Print (B)
test2 (. 1) #. 1. 6
# Example Three
B =. 6
DEF Test3 (a):
Print (a)
Print (B) when the function execution # still being given to this point
# UnboundLocalError: local variable 'B' before referenced assignment
B # =. 9 more than two exemplary line assignment
test3 (1)

Learned other languages, such as Java, for example the results of three would be more surprised, a similar situation, not an error in Java, will refer to external global variables, and if reassigned internally, with local variables will be used again value. The situation is not the same in Python, when compiling its function, was found to have the operation b assignment, it is determined that b is a local variable, so when you print b, it will go to query the local variable b, we found no assignment, it will throw an exception.

Reference "fluent Python" in this explanation:

This is not a defect, but a design choice: Python is not required to declare a variable, but it is assumed the assignment in the function definition body variables are local. This is much better than the behavior of JavaScript, JavaScript is not required to declare variables, but if you forget to declare a variable as a local variable (using var), may get full of local variables in knowledge.

The first look at the upper words may not quite understand, in fact it simply, Python is so designed that it believes in the function body, if there is assignment to a variable, then it proves that this variable is a local variable, and it will only to read data from a local variable. Such design avoids us, without knowing, to get the value of a global variable, leading to some erroneous data.

As a solution, it is to use the global keyword, to illustrate our use of global variables. Examples are as follows:

b = 6
def test4(a):
print(a)
global b # 1
print(b) # 6
b = 9
print(b) # 9
test4(1)

2. Define closure: In simple terms, the concept of closure is that when we define a function within a function, this function uses internal temporary variables of the outer function and external function's return value is a reference to the inner function, we call closure. Bit around

code show as below:

# A simple implementation calculating an average code 

DEF get_avg ():
Scores = [] # external temporary variables

def inner_count_avg (val): # internal function for calculating an average value
scores.append (val) # external function using provisional variable
return sum (scores) / len ( scores) # returns the calculated average

return inner_count_avg # external function returns a reference to an internal function

AVG = get_avg ()
Print (AVG (10)) # 10
Print (AVG (. 11)) # 10.5
...

3.nonlocal keywords. The above code, there is a small defect, a lot of repeated calculations, when we want to pass to get a new value of the new average value, the sum of the other previous time can be stored by an external temporary variables. So we naturally think of the following code:

Code # improved version of a simple implementation of a calculation of the average 
DEF get_avg ():
Scores 0 = # external temporary variable to an integral value in the list to
count = 0 # while adding a variable, the number of recording
def inner_count_avg ( val): # internal function for calculating the average
scores + = val # external functions using temporary variables
COUNT + =. 1
return Scores / COUNT # returns the calculated average
return inner_count_avg # external function returns a reference to an internal function
avg = get_avg ()
Print (AVG (10)) # error
...

The reason this error, see point 1: variable action rules. Because scores + = val, in fact, scores = scores + val, with the assignment, it is considered scores of local variables. And we have no way to use the global keyword, because the scores and the count is defined within get_ave function, which is both a local variable. And why do we use list, it does not appear this problem? Is well understood, because we are using list.append () method, it does not have an assignment. You can simply think, mutable objects (that is, we can change by calling some of its ways of doing additions and deletions and the variable address value is unchanged) this problem does not exist, then there will not mutable objects.

We introduce a nonlocal keyword in the Python 3 solves this problem:

# A simple calculation of the average achieved an improved version of the code two 
DEF get_avg ():
Scores 0 = # external temporary variable to an integral value in the list to
count = 0 # while adding a variable, the number of recording
def inner_count_avg ( val): # internal function for calculating an average value
nonlocal COUNT, Scores
Scores + # = Val external functions using temporary variables
COUNT + =. 1
return Scores / COUNT # returns the calculated average
return inner_count_avg # external function returns the internal function reference
AVG = get_avg ()
Print (AVG (10)) # error

You might say that in an environment Python 2 should be how to solve it? emm ~ In fact, it is a way, the idea is to become an immutable object variable object can be. Specific code as follows:

# - * - Coding: UTF-. 8 - * - 
class Score:
Pass
DEF get_avg ():
S = Score () # on the class object
s.scores = 0.0 # Note that the integer division is discarded fraction Python 2, so to define a floating point
s.count = 0
DEF inner_get_avg (Val):
s.count + =. 1
s.scores + = Val
return s.scores / s.count
return inner_get_avg
AVG = get_avg ()
Print (AVG (10)) # 10.0
print (avg (11)) # 10.5

4. Application of closure: first decorator, decorator is to modify the function to be decorated, to achieve add new function. When we are inside a function to modify the function to be decorated, in most cases it will be used to closures. A simple example:

def decorator (func): # external function of local variables FUNC 
DEF wrapper (* args, ** kwargs): # accept being passed over wrapper function parameters
return func (* args, ** kwargs ) # using local external functions variable FUNC
return warpper
@decorator
DEF basic_func (name):
Print 'My name IS', name
# is equivalent to
decorator_func (func)

Another application example of the averaging before we can see, the efficiency can be improved when the calculation is repeated. Second, there is a more important application scenarios, is the use of "lazy evaluation" this feature, this has reflected in the QuerySet in Django. When we do use ORM SQL queries, often based on different judgments conditions, to increase filter, plus filter time does not really do a query, when the final results really get to perform the query.

Here also, according to some Python common interview questions that we normally see with you to talk about the closure of Python, there are complementary partners welcome message to add Ha! I hope that we can learn from each other, progress ah!

Guess you like

Origin www.cnblogs.com/cherry-tang/p/11202194.html