【自记】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 声明后,才能 "修改" 外层函数的变量

相关推荐
独好紫罗兰2 小时前
对python的再认识-基于数据结构进行-a003-列表-排序
开发语言·数据结构·python
AIFarmer2 小时前
在EV3上运行Python语言——无线编程
python·ev3
不会代码的小测试2 小时前
UI自动化-POM封装
开发语言·python·selenium·自动化
2401_841495642 小时前
【LeetCode刷题】二叉树的层序遍历
数据结构·python·算法·leetcode·二叉树··队列
ZH15455891312 小时前
Flutter for OpenHarmony Python学习助手实战:GUI桌面应用开发的实现
python·学习·flutter
B站计算机毕业设计超人2 小时前
计算机毕业设计Hadoop+Spark+Hive招聘推荐系统 招聘大数据分析 大数据毕业设计(源码+文档+PPT+ 讲解)
大数据·hive·hadoop·python·spark·毕业设计·课程设计
B站计算机毕业设计超人3 小时前
计算机毕业设计hadoop+spark+hive交通拥堵预测 交通流量预测 智慧城市交通大数据 交通客流量分析(源码+LW文档+PPT+讲解视频)
大数据·hive·hadoop·python·spark·毕业设计·课程设计
CodeSheep程序羊3 小时前
拼多多春节加班工资曝光,没几个敢给这个数的。
java·c语言·开发语言·c++·python·程序人生·职场和发展
独好紫罗兰3 小时前
对python的再认识-基于数据结构进行-a002-列表-列表推导式
开发语言·数据结构·python
机器学习之心HML3 小时前
多光伏电站功率预测新思路:当GCN遇见LSTM,解锁时空预测密码,python代码
人工智能·python·lstm