[Learn python from zero] 31. In-depth understanding of higher-order functions and closures in Python

higher order functions

In Python, a function is actually a data type.

def test():
    return 'hello world'

print(type(test))  # <class 'function'>

The data type corresponding to the function is function, which can be regarded as a complex data type.

Since it is also a data type, we can treat it as a number or a string.

define a variable pointing to the function

In Python, we can also define a variable to point to a function, which is equivalent to giving the function an alias.

def test():
    return 'hello wrold'

fun = test   # 定义了一个变量fun,让它指向了 test 这个函数
print(fun())   # 使用fun()可以直接调用test这个函数

print(id(fun))  # 1819677672040
print(id(test))  # 1819677672040

Note: When defining a variable to represent a function, parentheses cannot be added after the function! Parentheses indicate that the function is called.

def test():
    return 'hello world'

result = test()   # 这种写法是调用test函数,并把函数的返回值赋值给result变量
print(result())   # 这里会报错  TypeError: 'str' object is not callable

fun = test   # 这种写法是给test函数起了一个别名,注意,这里的test后面不能加()
fun()        # 可以使用别名调用这个函数

higher order functions

Since variables can point to functions, and function parameters can receive variables, then a function can receive another function as a parameter. Similarly, we can also use a function as the return value of another function. This way of using functions is called a higher-order function.

function as an argument to another function

def test(age, action):
    if age < 18:
        print('您还没满十八岁,请退出')
    action()   # 把参数action直接当做一个函数来调用

def smoke():
    print('我已经年满十八岁了,我想抽烟')

my_action = smoke  # 定义一个变量my_action,让它指向smoke函数
test(21, my_action)  # 将my_action传给test函数作为它的参数

test(21, smoke)  # 还可以不再定义一个新的变量,直接传入函数名

function as return value of another function

def test():
    print('我是test函数里输入的内容')

def demo():
    print('我是demo里输入的内容')
    return test  # test 函数作为demo函数的返回值

result = demo()  # 我是demo里输入的内容  调用 demo 函数,把demo函数的返回值赋值给 result
print(type(result)) # <class 'function'>  result 的类型是一个函数

result() # 我是demo里输入的内容    我是test函数里输入的内容   既然result是一个函数,那么就可以直接使用() 调用这个函数

demo()()  # 我是demo里输入的内容    我是test函数里输入的内容

Closure

A function is just a piece of executable code, which is "solidified" after compilation. There is only one instance of each function in memory, and the function can be executed after getting the entry point of the function. Functions can also be defined nested, that is, another function can be defined inside a function. With the structure of nested functions, closure problems will arise.

function nesting

Functions can also be defined in the function, and multiple layers can be nested, and the execution needs to be called.

def outer():
    print('outer----hello')
    def inner():  # inner这个函数是在outer函数内部定义的
        print('inner----hello')
    inner()  # inner函数只在outer函数内部可见

outer()
# inner()  这里会报错,在outer函数外部无法访问到inner函数

What is a closure

A closure is an entity composed of a function and its associated reference environment (ie: closure = function block + reference environment).

def outer(n):
    num = n
    def inner():
        return num+1
    return inner

print(outer(3)())  # 4
print(outer(5)())  # 5

In this program, the function inner is the nested function of the function outer, and the inner function is the return value of the outer function. We noticed a problem: the local variable num in the outer function is referenced in the built-in function inner. How will the Python interpreter handle this problem? Let's take a look at the running results of this code first. When we call the functions obtained by calling the outer function with different parameters, the results are isolated (do not affect each other), that is to say, after each call to the outer function Both will generate and save a new local variable num, where the outer function returns the closure. If inside an inner function, references are made to variables in the outer scope (but not in the global scope), then the inner function is considered to be a closure.

Modify the value of an external variable

By default, external variables cannot be modified in a closure.

def outer(n):
    num = n
    def inner():
        num = num + 1
        return num
    return inner

print(outer(1)())

When the above code runs, an error will be reported!

UnboundLocalError: local variable 'num' referenced before assignment

Cause Analysis

In python, as long as you see an assignment statement, you will think that the left side of the assignment statement is a local variable. num = num + 1In this code, numon =the left side, the python parser will think that we want to modify this local variable innerin the function num, and this variable is undeclared before it is used, so it will report an error.

solution

We have analyzed that the reason for the error is that when we modify the external variable in the closure, it will be misunderstood by the python parser as a local variable of the internal function. So, the solution is that we need to find a way to let the parser know that we are not modifying local variables, but external variables.

Workaround: use nonlocalthe keyword

def outer(n):
    num = n
    def inner():
        nonlocal num  # 修改前使用nonlocal关键字对 num 变量进行说明
        num = num + 1
        return num
    return inner

print(outer(2)())

Advanced case

[Python] Python realizes the word guessing game-challenge your intelligence and luck!

[python] Python tkinter library implements GUI program for weight unit converter

[python] Use Selenium to get (2023 Blog Star) entries

[python] Use Selenium and Chrome WebDriver to obtain article information in [Tencent Cloud Studio Practical Training Camp]

Use Tencent Cloud Cloud studio to realize scheduling Baidu AI to realize text recognition

[Fun with Python series [Xiaobai must see] Python multi-threaded crawler: download pictures of emoticon package websites

[Play with Python series] [Must-see for Xiaobai] Use Python to crawl historical data of Shuangseqiu and analyze it visually

[Play with python series] [Must-see for Xiaobai] Use Python crawler technology to obtain proxy IP and save it to a file

[Must-see for Xiaobai] Python image synthesis example using PIL library to realize the synthesis of multiple images by ranks and columns

[Xiaobai must see] Python crawler actual combat downloads pictures of goddesses in batches and saves them locally

[Xiaobai must see] Python word cloud generator detailed analysis and code implementation

[Xiaobai must see] Python crawls an example of NBA player data

[Must-see for Xiaobai] Sample code for crawling and saving Himalayan audio using Python

[Must-see for Xiaobai] Technical realization of using Python to download League of Legends skin pictures in batches

[Xiaobai must see] Python crawler data processing and visualization

[Must-see for Xiaobai] Python crawler program to easily obtain hero skin pictures of King of Glory

[Must-see for Xiaobai] Use Python to generate a personalized list Word document

[Must-see for Xiaobai] Python crawler combat: get pictures from Onmyoji website and save them automatically

Xiaobai must-see series of library management system - sample code for login and registration functions

100 Cases of Xiaobai's Actual Combat: A Complete and Simple Shuangseqiu Lottery Winning Judgment Program, Suitable for Xiaobai Getting Started

Geospatial data processing and visualization using geopandas and shapely (.shp)

Use selenium to crawl Maoyan movie list data

Detailed explanation of the principle and implementation of image enhancement algorithm Retinex

Getting Started Guide to Crawlers (8): Write weather data crawler programs for visual analysis

Introductory Guide to Crawlers (7): Using Selenium and BeautifulSoup to Crawl Douban Movie Top250 Example Explanation [Reptile Xiaobai must watch]

Getting Started Guide to Crawlers (6): Anti-crawlers and advanced skills: IP proxy, User-Agent disguise, Cookie bypass login verification and verification code identification tools

Introductory Guide to Crawlers (5): Distributed Crawlers and Concurrency Control [Implementation methods to improve crawling efficiency and request rationality control]

Getting started with crawlers (4): The best way to crawl dynamic web pages using Selenium and API

Getting Started Guide to Crawlers (3): Python network requests and common anti-crawler strategies

Getting started with crawlers (2): How to use regular expressions for data extraction and processing

Getting started with reptiles (1): Learn the basics and skills of reptiles

Application of Deep Learning Model in Image Recognition: CIFAR-10 Dataset Practice and Accuracy Analysis

Python object-oriented programming basics and sample code

MySQL database operation guide: learn how to use Python to add, delete, modify and query operations

Python file operation guide: encoding, reading, writing and exception handling

Use Python and Selenium to automate crawling#【Dragon Boat Festival Special Call for Papers】Explore the ultimate technology, and the future will be due to you"Zong" #Contributed articles

Python multi-thread and multi-process tutorial: comprehensive analysis, code cases and optimization skills

Selenium Automation Toolset - Complete Guide and Tutorials

Python web crawler basics advanced to actual combat tutorial

Python introductory tutorial: master the basic knowledge of for loop, while loop, string operation, file reading and writing and exception handling

Pandas data processing and analysis tutorial: from basics to actual combat

Detailed explanation of commonly used data types and related operations in Python

[Latest in 2023] Detailed Explanation of Six Major Schemes to Improve Index of Classification Model

Introductory Python programming basics and advanced skills, web development, data analysis, and machine learning and artificial intelligence

Graph prediction results with 4 regression methods: Vector Regression, Random Forest Regression, Linear Regression, K-Nearest Neighbors Regression

Guess you like

Origin blog.csdn.net/qq_33681891/article/details/132317663