current position:Home>[Python] closure and scope

[Python] closure and scope

2022-02-01 13:10:58 Hazelnut

「 This is my participation 11 The fourth of the yuegengwen challenge 7 God , Check out the activity details :2021 One last more challenge

Closure

A closure is a function that extends its scope , It contains references in the function definition body 、 But non global variables that are not defined in the definition body . It doesn't matter if the function is anonymous , The key is that it can access non global variables defined outside the definition body .

Closures are defined in terms of expression ( explain ) by : If it's in an internal function , On the external scope ( But not in the global scope ) The variables are quoted , So internal functions are considered closures .

Closure is a function , It preserves the binding of free variables that exist when defining functions , When a function is called like this , Although the definition scope is not available , But you can still use those bindings .

Only functions nested in other functions may need to deal with external variables that are not in the global scope .

Take a chestnut :

#  Calculate the moving average 
def make_averager():
    series = []
    
    def averager(new_value):
        series.append(new_value)
        total = sum(series)
        return total / len(series)
    
    return averager

avg = make_averager()
avg(10)			# 10.0
avg(11)			# 10.5
avg(12)			# 11.0
 Copy code 

stay averager Function ,series It's a free variable (free variable). It's a technical term , Refers to variables that are not bound in the local scope . If averager There is a number in the function 、 character string 、 Tuples or any other variable of immutable type , And assign a value to it , Then this variable will become a local variable , The subsequent call will report an error .

Variable scope rule

def f1(a):
    print(a)
    print(b)

f1(3)   # 3 NameError: global name 'b' is not defined

b = 6
f1(3)   # 3 6

def f2(a):
    print(a)
    print(b)
    b = 9

b = 6
f2(3)   # 3 UnboundLocalError: local variable 'b' referenced before assignment
 Copy code 

In the above code ,f2 in ,Python When compiling the definition body of a function , Judge b It's a local variable , Because it's assigned a value in the function .( You can use the generated bytecode ( dis(f2) ) Confirm this judgment ),Python Will try to get... From the local environment b . Call back f2(3) when , f2 To get and print local variables a Value , But try to get local variables b The value of , Find out b No binding value .

If you want the interpreter to put b As global variables , To use global Statement , Such as :

def f3():
    global b
    print(b)
    b = 9

b = 6
f3()   # 6
 Copy code 

nonlocal Statement

nonlocal The purpose of the declaration is to mark the variable as a free variable , Even if the variable is given a new value in the function , It will also become a free variable . If nonlocal The declared variable is given a new value , The bindings saved in the closure will also be updated .

Take a chestnut :

#  Calculate the moving average   Don't save all history 
def make_averager():
    count = 0
    total = 0
    
    def averager(new_value):
        nonlocal count, total
        count += 1
        total += new_value
        return total / count
    
    return averager
 Copy code 

copyright notice
author[Hazelnut],Please bring the original link to reprint, thank you.
https://en.pythonmana.com/2022/02/202202011310553087.html

Random recommended