Python中的global与nonlocal关键字详解

一、前言

在Python编程中,变量作用域是一个非常重要的概念。对于初学者来说,经常会遇到在函数内部无法修改外部变量的问题。这时候,globalnonlocal关键字就能派上用场了。本文将详细介绍这两个关键字的用法、区别以及适用场景,帮助Python小白彻底理解它们。

二、Python变量的作用域

在讲解globalnonlocal之前,我们需要先了解Python中变量的作用域。Python中有四种作用域:

  1. 局部作用域(Local):在函数内部定义的变量

  2. 嵌套函数作用域(Enclosing):在嵌套函数中,外层函数的作用域

  3. 全局作用域(Global):在模块级别定义的变量

  4. 内置作用域(Built-in):Python内置的变量名

变量查找的顺序遵循LEGB规则:Local -> Enclosing -> Global -> Built-in

三、global关键字

3.1 global的基本用法

global关键字用于在函数内部声明一个变量来自全局作用域,并允许在函数内部修改这个全局变量。

x = 10  # 全局变量def func():global x  # 声明x是全局变量x = 20    # 修改全局变量x的值func()
print(x)  # 输出: 20

如果不使用global关键字,函数内部对变量的修改只会创建一个新的局部变量:

x = 10def func():x = 20  # 这里创建的是局部变量,不是修改全局变量func()
print(x)  # 输出: 10(全局变量未被修改)

3.2 global的常见用途

  1. 在函数内修改全局变量

counter = 0def increment():global countercounter += 1increment()
print(counter)  # 输出: 1
  1. 在函数内定义全局变量

def set_global():global g_varg_var = "I'm global"set_global()
print(g_var)  # 输出: I'm global

3.3 global的注意事项

  1. 在函数内部使用global声明的变量,如果在全局作用域中不存在,Python会在调用该函数时自动在全局作用域中创建这个变量。

  2. 过度使用global会使代码难以维护和理解,因为它破坏了函数的封装性。在大多数情况下,更好的做法是通过函数参数和返回值来传递数据。

  3. global语句可以出现在函数内的任何位置,但建议放在函数开头以提高代码可读性。

四、nonlocal关键字

nonlocal关键字是在Python 3.x中引入的,用于在嵌套函数中修改外层(非全局)作用域中的变量。

4.1 nonlocal的基本用法

def outer():x = 10def inner():nonlocal x  # 声明x来自外层函数作用域x = 20     # 修改外层函数的xinner()print(x)  # 输出: 20outer()

如果不使用nonlocal关键字,内层函数对变量的修改会创建一个新的局部变量:

def outer():x = 10def inner():x = 20  # 这里创建的是inner的局部变量inner()print(x)  # 输出: 10(外层变量未被修改)outer()

4.2 nonlocal的常见用途

  1. 在闭包中修改外层变量

def counter():count = 0def increment():nonlocal countcount += 1return countreturn incrementc = counter()
print(c())  # 输出: 1
print(c())  # 输出: 2
  1. 在多层嵌套函数中修改非局部变量

def outer():x = 1def middle():nonlocal xx = 2def inner():nonlocal xx = 3inner()middle()print(x)  # 输出: 3outer()

4.3 nonlocal的注意事项

  1. nonlocal声明的变量必须在外层函数中已经存在,否则会引发SyntaxError

  2. nonlocal不能用于访问全局变量,它只能用于嵌套函数中访问外层函数的变量。

  3. global类似,过度使用nonlocal也会使代码难以理解和维护。

五、global与nonlocal的区别

特性globalnonlocal
引入版本Python 2.xPython 3.x
作用范围全局作用域外层(非全局)函数作用域
变量要求变量可以不存在(会创建)变量必须已在外层函数中定义
使用场景函数内修改全局变量嵌套函数内修改外层函数变量
多层嵌套效果总是引用最外层的全局作用域引用最近的外层函数作用域

六、实际应用示例

6.1 使用global实现配置管理

# 全局配置
config = {'debug': True,'log_level': 'INFO'
}def set_debug_mode(enable):global configconfig['debug'] = enableif enable:config['log_level'] = 'DEBUG'else:config['log_level'] = 'INFO'print("初始配置:", config)
set_debug_mode(False)
print("修改后配置:", config)

6.2 使用nonlocal实现计数器工厂

def make_counter(initial=0, step=1):count = initialdef counter():nonlocal countcurrent = countcount += stepreturn currentreturn counter# 创建两个不同的计数器
c1 = make_counter(10, 2)
c2 = make_counter()print(c1(), c1())  # 输出: 10 12
print(c2(), c2())  # 输出: 0 1

6.3 混合使用global和nonlocal

global_var = "global"def outer():enclosing_var = "enclosing"def inner():global global_varnonlocal enclosing_varlocal_var = "local"global_var = "modified global"enclosing_var = "modified enclosing"print(f"局部: {local_var}")print(f"外层: {enclosing_var}")print(f"全局: {global_var}")inner()print("outer中:", enclosing_var)outer()
print("全局中:", global_var)

七、常见问题解答

Q1: 为什么不建议频繁使用global和nonlocal?

A: 频繁使用globalnonlocal会破坏代码的封装性和可维护性,使得变量的修改难以追踪,增加了代码的复杂性。良好的编程实践应该尽量减少函数对外部状态的依赖。

Q2: global和nonlocal可以同时用于同一个变量吗?

A: 不可以。一个变量要么是全局的(使用global),要么是外层函数的(使用nonlocal),不能同时是两者。

Q3: 如何在函数内部访问(不修改)全局变量?

A: 在函数内部可以直接访问全局变量而无需使用global关键字,只有在需要修改时才需要使用global

x = 10def show_x():print(x)  # 可以直接访问show_x()  # 输出: 10

Q4: nonlocal能引用多级外层变量吗?

A: nonlocal会查找最近的外层函数中的变量,不能直接跳过中间层级引用更外层的变量。

def outer():x = 1def middle():x = 2def inner():nonlocal x  # 这里引用的是middle中的x,不是outer中的xx = 3inner()print("middle:", x)  # 输出: 3middle()print("outer:", x)  # 输出: 1outer()

八、总结

  1. global用于在函数内部修改全局变量,nonlocal用于在嵌套函数中修改外层函数的变量。

  2. 使用global时,如果全局变量不存在会自动创建;使用nonlocal时,外层变量必须已存在。

  3. 两个关键字都应谨慎使用,过度使用会导致代码难以维护。

  4. 在大多数情况下,通过函数参数和返回值来传递数据是更好的选择。

  5. 理解变量作用域(LEGB规则)是掌握globalnonlocal的关键。

希望通过本文的讲解,您能彻底理解Python中globalnonlocal的用法和区别。在实际编程中,建议优先考虑使用函数参数和返回值来传递数据,只有在确实需要时才使用这两个关键字。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/82054.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue-qr生成的二维码增加下载功能

大家好!今天给大家分享一个超实用的前端小技巧——如何在 Vue 项目中生成二维码并实现下载功能。这个功能在分享链接、活动推广等场景特别有用,一起来学习吧! 🔍 功能预览 使用 vue-qr 生成美观二维码点击按钮即可下载 PNG 格式的…

嵌入式C进阶路线指南

嵌入式是工科,工科讲究实践。说的再多、懂得再多,不能做出实际的东西,是没有意义的。学习嵌入式的核心原则之一就是多动手写代码。另外还有一个原则就是:从浅到深学习。接下来的内容将贯彻这两个原则。最后强调一点,各…

服务器上机用到的设备

服务器上机通常需要以下硬件设备: 服务器主机: CPU:选择高性能的多核处理器,如英特尔至强(Xeon)系列或AMD EPYC系列,以满足高并发和多任务处理需求。 内存(RAM)&#xf…

FreeCAD傻瓜教程-涡轮蜗杆的快速绘制FCGear工作台的使用方法

起因:涡轮蜗轴的组合,是一种比较简单且高效的传动结构。可以实现减速、加速、转动角度的放大、缩小等应用。 如何绘制呢?我搜索了不少教程,看起来都挺复杂的,对于小白来说有点像天书。这里介绍和记录一下利用FreeCAD 的…

daplink开发_一次开发DAPLink的详细开发流程及调试步骤

以下是针对第一次开发DAPLink的详细开发流程及调试步骤,结合STM32平台特性,分阶段指导您完成从零到一的完整开发过程: 一、开发流程1. 硬件准备阶段选型STM32芯片:推荐型号:STM32F103C8T6(成本低、资源足够)、STM32F405RGT6(性能更强,支持更多外设)。关键外设需求:U…

给小白的AI Agent 基本技术点分析与讲解

引言:重塑交互与自动化边界的 AI Agent 在人工智能技术飞速发展的浪潮中,AI Agent(智能体)概念的兴起标志着自动化和人机交互正迈向一个全新的阶段。传统的软件系统通常被设计来执行精确预设的指令序列,它们强大且高效…

Mysql常用语句汇总

Mysql语句分类 DDL: 数据定义语言,用来定义数据库对象(数据库、表、字段)DML: 数据操作语言,用来对数据库表中的数据进行增删改DQL: 数据查询语言,用来查询数据库中表的记录DCL: 数据控制语言,用来创建数据…

【Python 模块】

Python 中的模块(Module)是组织代码的核心方式,通过将相关函数、类和变量封装到独立文件中,实现代码复用和结构化管理。以下是模块的核心知识点: 一、基础概念 1. 模块定义 任何 .py 文件都是一个模块模块名即文件名…

黑电平校正(Black Level Correction, BLC)算法

黑电平校正(Black Level Correction, BLC)算法 黑电平校正(BLC)是图像传感器(如CMOS/CCD)信号处理中的一个重要步骤,主要用于消除传感器暗电流(Dark Current)导致的基线…

处理PostgreSQL数据库事务死锁过程

查询pg_locks表,获取未得到满足的锁信息: select * from pg_locks where granted is false ; --查询得不到锁的,那就是两个互相等待对方持有的锁查询活动的事务会话进程,和上一步的锁的事务对应起来: select * from …

Android开发-文本显示

在Android应用开发中,文本显示是用户界面设计中最基本也是最重要的部分之一。无论是展示欢迎信息、错误提示还是动态内容,合理地使用文本元素能够极大地提升用户体验。本文将详细介绍如何在Android应用中有效地显示文本,包括使用TextView组件…

基于大模型的输卵管妊娠全流程预测与治疗方案研究报告

一、引言 1.1 研究背景与意义 输卵管妊娠作为异位妊娠中最为常见的类型,严重威胁着女性的生殖健康和生命安全。受精卵在输卵管内着床发育,随着胚胎的生长,输卵管无法提供足够的空间和营养支持,极易引发输卵管破裂、大出血等严重并发症,若救治不及时,甚至会导致孕产妇死…

当向量数据库与云计算相遇:AI应用全面提速

如果将AI比作一台高速运转的机器引擎,那么数据便是它的燃料。 然而,存储数据的燃料库--传统数据库,在AI时代的效率瓶颈愈发明显,已经无法满足AI对于数据的全新需求。 因此,向量数据库近年来迅速崛起。向量数据库通过…

Media3 中 Window 的时间相关属性详解

AndroidX Media3 的 Timeline.Window 类中,与时间相关的属性描述了媒体播放窗口(window)在时间维度上的关键信息。这些属性帮助开发者理解媒体的播放范围、起始点、持续时间以及与设备时间或直播流的同步关系。 Timeline.Window 的时间相关属…

【Python爬虫电商数据采集+数据分析】采集电商平台数据信息,并做可视化演示

前言 随着电商平台的兴起,越来越多的人开始在网上购物。而对于电商平台来说,商品信息、价格、评论等数据是非常重要的。因此,抓取电商平台的商品信息、价格、评论等数据成为了一项非常有价值的工作。本文将介绍如何使用Python编写爬虫程序&a…

工业相机的芯片CRA角度与镜头选型的匹配关系

工业相机的芯片CRA角度与镜头选型的匹配关系 Baumer工业相机​工业相机的芯片CRA角度的技术背景​工业相机的芯片CRA的信息CRA相差过大的具体表现怎样选择工业相机sensor的CRABaumer工业相机sensor的CRA工业相机的芯片CRA角度与镜头匹配好的优点 Baumer工业相机 工业相机是常用…

深度学习中常见的矩阵变换函数汇总(持续更新...)

1. 转置操作 (Transpose) 概念:将矩阵的行和列互换应用场景: 在卷积神经网络中转换特征图维度矩阵乘法运算前的维度调整数据预处理过程中的特征重排 原始矩阵 A [[1, 2, 3], 转置后 A^T [[1, 4],[4, 5, 6]] [2, 5],[3, 6]]代码…

day 14 SHAP可视化

一、原理——合作博弈论 SHAP(SHapley Additive exPlanations)是一种用于解释机器学习模型预测结果的方法,它基于合作博弈论中的 Shapley 值概念。Shapley 值最初用于解决合作博弈中的利益分配问题。假设有 n 个参与者共同合作完成一项任务并…

从0开始学习大模型--Day03--Agent规划与记忆

规划(planning) 规划,可以为理解观察和思考。如果用人类来类比,当我们接到一个任务,我们的思维模式可能会像下面这样: 1、首先会思考怎么完成这个任务。 2、然后会审视手头上所拥有的工具,以及如何使用这…

使用 Couchbase Analytics Service 的典型步骤

下面是使用 Couchbase Analytics Service 的典型步骤,包括部署、配置、创建数据集、运行查询以及监控优化等环节。 首先,您需要安装并启用 Analytics 服务;然后将节点加入集群并重平衡;接着在 Analytics 中映射数据服务的集合&am…