【自记】Python 中 nonlocal 和 global 的区别,以及闭包的作用和示例

一、nonlocalglobal 的区别

作用范围
  • global :用于在函数内部声明一个变量是全局变量。如果在函数中使用 global 关键字声明了某个变量,那么在函数内部对该变量的操作,就是对全局作用域中这个变量的操作。例如:
python 复制代码
count = 10
def modify_count():
    global count
    count = 20
    print(count)

modify_count()  # 输出 20
print(count)    # 输出 20,全局变量count已经被修改
  • nonlocal :用于在嵌套函数中,声明一个变量不是当前函数的局部变量,而是来自外层(非全局)函数的变量。它使得内层函数可以修改外层函数中定义的变量,前提是外层函数中没有使用 global 声明这个变量。比如:
python 复制代码
def outer():
    num = 5
    def inner():
        nonlocal num
        num = 10
        print(num)
    inner()
    print(num)

outer()  
# 输出 10
# 输出 10,因为内层函数通过nonlocal修改了外层函数的num变量
适用场景
  • global:当需要在函数内部修改全局作用域中的变量时使用。
  • nonlocal:在函数嵌套的场景下,内层函数想要修改外层函数中定义的变量,且该变量不是全局变量时使用。

二、闭包的作用

数据隐藏与封装

闭包可以将一些数据(即外层函数的变量)与操作这些数据的函数绑定在一起,形成一个相对独立的单元,外界不能直接访问这些被 "隐藏" 的数据,只能通过闭包返回的函数来操作。例如,实现一个简单的计数器:

python 复制代码
def counter():
    count = 0
    def increment():
        nonlocal count
        count += 1
        return count
    return increment

count_func = counter()
print(count_func())  # 输出 1
print(count_func())  # 输出 2
print(count_func())  # 输出 3

在这个例子中,count 变量被隐藏在闭包内部,外界无法直接访问和修改,只能通过 increment 函数来对其进行递增操作,实现了数据的封装。

状态保持

闭包可以 "记住" 外层函数执行时的变量状态,方便在多次调用返回的函数时,基于之前的状态进行操作。比如模拟一个累加器:

python 复制代码
def accumulator(initial_value=0):
    def accumulate(num):
        nonlocal initial_value
        initial_value += num
        return initial_value
    return accumulate

acc = accumulator(5)
print(acc(3))  # 输出 8,初始值5加上传入的3
print(acc(2))  # 输出 10,基于上一次结果8再加上传入的2

这里闭包记住了 initial_value 的状态,每次调用 accumulate 函数时,都是基于上一次的状态进行累加操作。

函数复用

闭包可以创建具有特定初始状态的函数,方便在不同场景下复用。比如创建不同税率的计算函数:

python 复制代码
def tax_calculator(tax_rate):
    def calculate_tax(amount):
        return amount * tax_rate
    return calculate_tax

calculate_sales_tax = tax_calculator(0.08)  # 8% 的销售税
calculate_income_tax = tax_calculator(0.2)  # 20% 的所得税
print(calculate_sales_tax(100))  # 输出 8
print(calculate_income_tax(1000))  # 输出 200

通过 tax_calculator 函数创建不同税率的计算函数,这些函数都能复用内部计算逻辑,只是初始的税率不同。

三、注意

在 Python 中,内部函数本来就可以 "读取" 外层函数的变量(包括参数),但只有通过 nonlocal 声明后,才能 "修改" 外层函数的变量

相关推荐
snowfoootball12 小时前
python函数及面向过程高级特性
开发语言·python
DP+GISer12 小时前
基于站点数据进行遥感机器学习参数反演-以XGBOOST反演LST为例(附带数据与代码)试读
人工智能·python·机器学习·遥感与机器学习
工业互联网专业14 小时前
基于协同过滤算法的小说推荐系统_django+spider
python·django·毕业设计·源码·课程设计·spider·协同过滤算法
星星的月亮叫太阳14 小时前
large-scale-DRL-exploration 代码阅读 总结
python·算法
Q_Q196328847514 小时前
python+django/flask基于Echarts+Python的图书零售监测系统设计与实现(带大屏)
spring boot·python·django·flask·node.js·php
深度学习lover14 小时前
<数据集>yolo航拍交通目标识别数据集<目标检测>
人工智能·python·yolo·目标检测·计算机视觉·航拍交通目标识别
程序猿202314 小时前
Python每日一练---第二天:合并两个有序数组
开发语言·python
权泽谦15 小时前
用 Flask + OpenAI API 打造一个智能聊天机器人(附完整源码与部署教程)
python·机器人·flask
njxiejing15 小时前
Numpy一维、二维、三维数组切片实例
开发语言·python·numpy
lskisme16 小时前
springboot maven导入本地jar包
开发语言·python·pycharm