关于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的工作原理 启动某个程序后,将程序的代码从辅存中取出放入内存中,再从内存中将代码…

【安全】2.6.6版本的audit审计机制分析

文章目录 2.6.6版本的audit审计机制分析1 关于内核版本2 入口3 audit初始化4 系统调用审计流程5 配置下发流程6 总结 2.6.6版本的audit审计机制分析 1 关于内核版本 linux内核从2.6.6版本开始支持audit机制,为了更好的理解audit本身的机制,需要对audit…

机器人开发的选择

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

知识图谱06——将pdf中的表格(文字形式)保存至csv中

使用ubuntu22.04,anaconda 由于装环境装了一阵子,不确定装了哪些包了 可能的环境安装 conda install -c conda-forge pymupdf conda install -c conda-forge camelot-py conda install pandas #或者 pip install PyMuPDF pip install camelot-py[all] …

求链表环的起始位置

leetcode中题目位置 https://leetcode.cn/problems/linked-list-cycle-ii/submissions/?envTypestudy-plan-v2&envIdtop-100-liked 代码: public class Solution {public ListNode detectCycle(ListNode head) {if (head null || head.next null) {return…

S25FL系列FLASH读写的FPGA实现

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

Could not resolve all files for configuration ‘:app:androidJdkImage‘.

在使用./gradlew build编译项目时候遇到了该问题,整体错误如下: * What went wrong: Configuration cache state could not be cached: field generatedModuleFile of com.android.build.gradle.tasks.JdkImageInput bean found in field compilerArgumentProvider…

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元,怎么完成…

CMake中的变量: 描述系统信息的变量

文章目录 变量名称描述ANDROID当目标系统(CMAKE_SYSTEM_NAME)为Android时,设置为1。APPLE当目标系统是苹果平台(macOS、iOS、tvOS、visionOS或watchOS)时,设置为True。BORLAND如果正在使用Borland编译器&am…

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

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

数据结构总复习

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

qt 简单了解QHBoxLayout QVBoxLayout QFormLayout水平,垂直,表单布局管理器.

QHBoxLayout水平布局,QVBoxLayout垂直布局,QFormLayout表单布局管理器,是常用的布局管理器,是用代码编写应用界面必不可少的功能类. 1.tips 这里值得注意的是,2个单选按钮(QRadioButton)同时放进一个水平布局管理器(QHBoxLayout)中,相当于放进了一个分组器中,此时,2个单选按钮…

C++判断一个整数是否为回文数

可以将整数转换为字符串&#xff0c;然后再判断该字符串是否为回文串。 将整数转化为字符串&#xff0c;可以使用 to_string() 方法&#xff1b; 使用双指针法判断字符串是否为回文串。 #include <iostream> #include <string>using namespace std;bool isPalin…

Qt QString与QChar总结

(一) QString 1 QString的简介 QString 是Qt 中的一个类&#xff0c;用于存储字符串&#xff0c;QString 没有父类。QString 存储的是一串字符&#xff0c;每个字符是一个 QChar 类型的数据。QChar 使用的是 UTF-16 编码&#xff0c;一个字符包含 2字节数据。 对于超过 6553…

5 个 Python 异常值检测算法实战案例

异常值检测(outlier)是一种数据挖掘过程,用于确定数据集中发现的异常值并确定其出现的详细信息。当前自动异常检测至关重要,因为大量数据无法手动标记异常值。自动异常检测具有广泛的应用,例如信用卡欺诈检测,系统健康监测,故障检测以及传感器网络中的事件检测系统等。 …