Python basic tutorial: nested functions, closures

Nested function

  • Defining another function in a function is called a nested function.
  • Nested functions can access variables in the enclosing scope.
def print_msg(msg):

    def printer():
        print(msg)

    printer()

print_msg("Hello")  

执行结果:

Hello

Call of nested function

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
def func1():
    print('func1')
 
    def func2():
        print('func2')
 
func1()

执行结果:

func1

Why is the function func2 not executed?

After any function is defined, if no one calls it by name, it will never be executed. If it needs to be executed, it can be called as follows:

def func1():
    print('func1')
 
    def func2():
        print('func2')
     
    func2()
 
func1()

执行结果:

func1
func2

nonlocal keyword

The inner function changes the outer function variable to use nonlocal. Nonlocal cannot define new outer function variables, but can only change the existing outer function variables, while nonlocal cannot change global variables.
No nolocal keyword

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
def outer():
    a = 1

    def inner():
        a += 1
        print("Inner", a)

    inner()
    print("Outer", a)

outer()

执行结果:

---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
<ipython-input-9-7b758191e4f5> in <module>()
      9     print("Outer", a)
     10 
---> 11 outer()

<ipython-input-9-7b758191e4f5> in outer()
      6         print("Inner", a)
      7 
----> 8     inner()
      9     print("Outer", a)
     10 

<ipython-input-9-7b758191e4f5> in inner()
      3 
      4     def inner():
----> 5         a += 1
      6         print("Inner", a)
      7 

UnboundLocalError: local variable 'a' referenced before assignment

Add nolocal keyword

def outer():
    a = 1

    def inner():
        nonlocal a
        a += 1
        print("Inner", a)

    inner()
    print("Outer", a)

outer()

执行结果:

Inner 2
Outer 2

Closure

Closures are also called lexical closures. If in an internal function, a variable in the external scope (but not in the global scope) is referenced, then the internal function is considered to be a closure (closure). The domain is nonlocal.

Generally speaking, a closure is to use a function (method) as a variable.

The criteria that must be met to create a closure in python will be the following:

  • There must be a nested function (function inside a function).
  • The nested function must refer to the value defined in the enclosing function.
  • Closure functions must return nested functions.

Use a closure to implement a counter:

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
def counter():
    i = 0
    def nested():
        nonlocal i
        i += 1
        return i

    return nested

c = counter()
print(c(),c(),c(),end=" ")

The returned function is not executed immediately, but is not executed until c() is called.
Do not reference loop variables in the returned function:

def count():
    fs = []
    for i in range(1, 4):
        def f():
             return i*i
        fs.append(f)
    return fs

f1, f2, f3 = count()

print(f1()) 
print(f2()) 
print(f3())

执行结果:

9
9
9

All are 9! The reason is that the returned function references the variable i, but it is not executed immediately. When all three functions return, the variable i they refer to has become 3, so the final result is 9.

If you must use a loop variable, the solution is to create another function and bind the current value of the loop variable with the parameter of the function. No matter how the loop variable is subsequently changed, the value bound to the function parameter remains unchanged:

def count():
    def f(j):
        def g():
            return j*j
        return g
    
    fs = []
    for i in range(1, 4):
        fs.append(f(i)) # f(i)立刻被执行,因此i的当前值被传入f()
    return fs


f1, f2, f3 = count()

print(f1()) 
print(f2()) 
print(f3())

执行结果:

1
4
9

Guess you like

Origin blog.csdn.net/qdPython/article/details/112613385
Recommended