关于python中的nonlocal关键字

如果在函数的子函数中需要调用外部变量,一般会看见一个nonlocal声明,类似下面这种:

def outer_function():x = 10def inner_function():nonlocal xx += 1print(x)inner_function()outer_function()

在这个例子中,inner_function 引用了外部函数 outer_function 中的变量 x,并对其进行了修改。由于涉及修改外部函数的变量,所以需要使用 nonlocal 关键字。

如果在 inner_function 中不使用 nonlocal,而直接对 x 进行修改,Python 将认为 x 是一个新的局部变量,并在 inner_function 中创建一个新的局部变量 x,而不会修改外部函数 outer_function 中的 x。
这个时候运行会出现报错:
在这里插入图片描述
到上面为止都很容易理解。
但是迷惑的点在于我经常看见子函数应用外部变量,但没有进行nonlocal的声明,比如下面这种:

def outer_function():x = [10]def inner_function():x.append(2)print(x)inner_function()
outer_function()

这里inner_function 也引用了外部函数 outer_function 中的变量 x,并对其进行了修改,但并没有声明nonlocal,这是为什么?
原因是:
在这个特定的情况下,x是一个可变对象(列表),而不是不可变对象。在 Python 中,对于可变对象(如列表、字典等),可以在不使用 nonlocal 的情况下在函数内部修改它们的值,因为它们是通过引用传递的。

当你在函数内部修改一个可变对象时,实际上是在原地修改这个对象,而不是重新绑定变量。因此,对于列表 x,你可以在函数内部追加或删除元素,而无需使用 nonlocal。

如果 x是一个不可变对象,例如数字、字符串或元组,你将需要使用 nonlocal 关键字,因为对于不可变对象,重新绑定变量是唯一的方式来修改它们的值。

总的来说,对于可变对象,你可以在函数内部修改它们的值,而不需要 nonlocal 关键字。而对于不可变对象,你通常需要使用 nonlocal 或者返回修改后的值并重新赋给外部变量。

需要注意的事,就算在函数内部引用一个外部的可变对象变量,如果涉及到对该变量的重新赋值,也需要加nonlocal

def outer_function():x = [1,2,3]def inner_function():nonlocal  xx = x+[2]# x.append(2)print(x)inner_function()outer_function()
def outer_function():x =  [1,2,3]def inner_function():# nonlocal  x# x = x+[2]x.append(2)print(x)inner_function()outer_function()

要理解这两者的区别,关键是对于x = []这句的理解,在这里,x 是一个变量,它存储了对列表 [1, 2, 3] 的引用。这表示 x 指向了内存中存储这个列表的位置。而x + [2] 创建了一个新的列表 [1, 2, 3, 2],然后将这个新列表赋给了变量 x。现在,变量 x 指向了一个新的列表对象,发生了重新赋值。所以存在这种重新赋值的情况时,需要加一个nonlocal,这样才能在子函数外部接收到。

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

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

相关文章

【DevOps】基于 KubeSphere 的 Kubernetes 生产实践之旅(万字长文)

基于 KubeSphere 的 Kubernetes 生产实践 1.KubeSphere 简介1.1 全栈的 Kubernetes 容器云 PaaS 解决方案1.2 选型理由(从运维的角度考虑) 2.部署架构图3.节点规划3.1 软件版本3.2 规划说明3.2.1 K8s 集群规划3.2.2 存储集群3.2.3 中间件集群3.2.4 网络规…

SpringBoot——LiteFlow引擎框架

优质博文:IT-BLOG-CN 一、LiteFlow 简介 LiteFlow是一个轻量且强大的国产规则引擎框架,可用于复杂的组件化业务的编排领域。帮助系统变得更加丝滑且灵活。利用LiteFlow,你可以将瀑布流式的代码,转变成以组件为核心概念的代码结构…

计算机组成原理-Cache的基本概念和原理

文章目录 存储系统存在的问题Cache的工作原理局部性原理性能分析例题界定何为局部部分问题总结 存储系统存在的问题 增加Cache层来缓和CPU和主存的工作速度矛盾 Cache的工作原理 启动某个程序后,将程序的代码从辅存中取出放入内存中,再从内存中将代码…

机器人开发的选择

喷涂机器人 码垛机器人 纸箱码垛机器人 焊接机器人 跳舞机器人 管道清理机器人 工地巡检机器人 点餐机器人 化工巡检机器人 装箱机器人 安防巡检机器人 迎宾机器人好像有点像软银那个 污水管道检测机器人 大酒店用扫地机器人 家用扫地机器人 工厂用(…

S25FL系列FLASH读写的FPGA实现

文章目录 实现思路具体实现子模块实现top模块 测试Something 实现思路 建议读者先对 S25FL-S 系列 FLASH 进行了解,我之前的博文中有详细介绍。 笔者的芯片具体型号为 S25FL256SAGNFI00,存储容量 256Mb,增强高性能 EHPLC,4KB 与 6…

Leetcode199. 二叉树的右视图

Every day a Leetcode 题目来源:199. 二叉树的右视图 解法1:层序遍历 给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。 按层序遍历,将每层的…

如何判断一个题目用“贪心/动态规划“还是用“BFS/DFS”方法解决

1 总结 1.1 贪心、动态规划和BFS/DFS题解的关系 一般能使用贪心、动态规划解决一个问题时,使用BFS,DFS也能解决这个题,但是反之不能成立。 1.2 2 贪心 -> BFS/DFS 2.1 跳跃游戏1和3的异同 这两道题,“跳跃游戏”&#xf…

html实现各种瀑布流(附源码)

文章目录 1.设计来源1.1 动态响应瀑布流1.2 分页瀑布流1.3 响应瀑布流 2.效果和源码2.1 动态效果2.2 源代码 源码下载 作者:xcLeigh 文章地址:https://blog.csdn.net/weixin_43151418/article/details/134613121 html实现各种瀑布流(附源码),…

100元预算,轻松涨粉1000!腾讯运营面试秘籍大揭秘!

大家好啊!小米在这里~ 很高兴又有机会和大家见面啦!最近小米参加了一场腾讯的运营面试,遇到了一个超有趣的问题:如果让你运营一个公众号,近期需要增加1000个关注,预算100元,怎么完成…

【阿里云】图像识别 智能分类识别 项目开发(一)

语音模块和阿里云图像识别结合 环境准备 代码实现 编译运行 写个shell脚本用于杀死运行的进程 语音模块和阿里云图像识别结合 使用语音模块和摄像头在香橙派上做垃圾智能分类识别 语音控制摄像下载上传阿里云解析功能点实现 环境准备 将语音模块接在UART5的位置 在orange…

数据结构总复习

文章目录 线性表动态分配的顺序存储结构链式存储 线性表 动态分配的顺序存储结构 通过分析代码,我们发现,要注意什么: 要分清你的下标Insert 函数是可以用来没有元素的时候,增加元素的Init(或者Create )函数一般只用来分配空间…

go atexit源码分析

文章目录 atexit源码解析UML类图样例一: 程序退出之前执行注册函数1.1 流程图1.2 代码分析 样例二:使用cancel取消注册函数2.1 cancel流程图2.2 代码分析 样例三:使用Fatal/Fatalln/Fatal执行注册函数3.1 Fatal/Fatalln/Fatal流程图3.2 代码分析 atexit源…

Android平台GB28181设备接入模块开发填坑指南

技术背景 为什么要开发Android平台GB28181设备接入模块?这个问题不再赘述,在做Android平台GB28181客户端的时候,媒体数据这块,我们已经有了很好的积累,因为在此之前,我们就开发了非常成熟的RTMP推送、轻量…

Scannet v2 数据集介绍以及子集下载展示

Scannet v2 数据集介绍以及子集下载展示 文章目录 Scannet v2 数据集介绍以及子集下载展示参考数据集简介子集scannet_frames_25kscannet_frames_test 下载脚本 download_scannetv2.py 参考 scannet数据集简介和下载-CSDN博客 scannet v2 数据集下载_scannetv2数据集_蓝羽飞鸟的…

BeanUtil的正确使用方式

shigen日更文章的博客写手,擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长,分享认知,留住感动。 在实际的开发中,我们常常会用到工具类去拷贝对象的属性,将一个对象的属性转换成另外一个…

球面的表面积

此推导需要用到重积分的知识,另外关于曲面的面积公式可以看我之前的博客

百度AI布局:从财报看百度的核心竞争力和未来发展方向

百度是中国最大的搜索引擎,也是全球领先的人工智能(AI)公司。百度在2023年第三季度业绩中,展示了其在AI领域的强劲表现和广阔前景。 百度财报透露了关于AI业务的哪些重要信息? 百度在2023年第三季度的财报中&#xf…

机器学习:攻击方法FGSM系列

任务 FGSM I-FGSM MI-FGSM Ensemble Attack 攻击评价指标 准确率越低表明攻击越好 数据 预训练模型 BaseLine 实践

***Linux常用命令及解释

1、查看Linux的版本信息 1.1、uname -a 1.2、cat /etc/issue 1.3、cat /proc/version 1.4、hostnamectl 通过使用hostnamectl命令,可以查询和更改系统主机名,并且还可以查看Linux的发行版和内核版本。 2、删除文件 3、修改目录权限 4、解压文件 5、…

探索 Linux vim/vi 编辑器:介绍、模式以及基本操作演示

💐作者:insist-- 💐个人主页:insist-- 的个人主页 理想主义的花,最终会盛开在浪漫主义的土壤里,我们的热情永远不会熄灭,在现实平凡中,我们终将上岸,阳光万里 ❤️欢迎点…