Python中关键字global和nonlocal的区别详解
作者:一笑1990 发布时间:2023-08-02 16:42:33
前言
终于下定决心学习Python了。既然从头开始,就需要认认真真。
首先需要说的是,我是初学Python,这篇文章只是用于展示global和nonlocal关键字的区别,是很简单的知识点,如果你已经学过,可以绕道。因为不经常写博客,而且是个Python小白,所以内容有些啰嗦。。。
两个关键词都用于允许在一个局部作用域中使用外层的变量。
global 表示将变量声明为全局变量
nonlocal 表示将变量声明为外层变量(外层函数的局部变量,而且不能是全局变量)
注意:我使用的是Python3.6.3,可能和Python2有不同的地方,并未确认。
考虑到文章比较啰嗦,先把结论贴出来,避免浪费大家的时间:
第一,两者的功能不同。global关键字修饰变量后标识该变量是全局变量,对该变量进行修改就是修改全局变量,而nonlocal关键字修饰变量后标识该变量是上一级函数中的局部变量,如果上一级函数中不存在该局部变量,nonlocal位置会发生错误(最上层的函数使用nonlocal修饰变量必定会报错)。
第二,两者使用的范围不同。global关键字可以用在任何地方,包括最上层函数中和嵌套函数中,即使之前未定义该变量,global修饰后也可以直接使用,而nonlocal关键字只能用于嵌套函数中,并且外层函数中定义了相应的局部变量,否则会发生错误(见第一)。
接下来是得到结论的过程,有兴趣的可以浏览一下。
我们先来看一个代码片段,看看默认情况下输出结果是什么(不敢恭维CSDN显示代码的格式,这里使用图片,如果要验证,得麻烦各位动动指头了)。
输出结果:
上面的代码片段中没有使用global或nonlocal关键字,是为了看一下默认情况下的输出结果。
可以看到变量x在三次输出中是同一个变量(值相同,地址也相同),都是全局变量,在print函数中使用三个参数是为了方便识别变量,第一个参数是print运行的位置,第二个参数是变量x保存的值,第三个参数是变量x保存的值的地址(这个有待考证)。
如果我们在func函数中修改x的值呢?
输出结果:
可以看到func函数中x的值和地址都变了,但没有影响函数外边的x的值和地址(main1和main2的数据相同)。所以func函数内的x变量和函数外的x变量是两个变量,而func内的x变量是局部变量,修改它的值不影响全局变量。
第一回合:在函数内部使用了与全局变量同名的变量,如果不对该变量赋值(修改变量),那么该变量就是全局变量,如果对该变量进行赋值,那么该变量就是局部变量。
如果我们想在func函数内修改全局变量x呢?我们先试试用global(全局)。
运行后报错,提示语法错误。原来global修饰变量时不能直接赋值,修改为如下:
运行结果:
可以看到main1位置的x和func内部func1位置的x是同一个值,但和func内部的func2以及main2位置的x不一样了,反而是main2处的x和func内部的x变量是同一个。
第二回合:global关键字修饰函数内部变量后标志其是全局变量(这里不能说global将x从局部变量改为了全局变量),如果用global修饰函数内的变量,必须在使用该变量前进行修饰(否则会发生变量未定义的错误,请你自己尝试一下)。
我们试试nonlocal关键字呢?
报错了,无法使用nonlocal关键字。
接下来我们看看怎样使用nonlocal关键字。
我们先添加一个嵌套函数:
输出结果:
可以看到嵌套函数内默认使用的也是全局变量。我们在func函数中修改一下x的值试试。
输出结果:
可以看到在func函数中修改x后,x被标识成局部变量,它的改变并没有影响全局变量x,但嵌套函数ifunc中的x受到了影响,显示ifunc中的x是func函数中的局部变量。
我们再继续修改一下ifunc中x的值。
输出结果:
可以看到在ifunc修改x的之后即没有影响func中的局部变量x,也没有影响全局变量x,ifunc中的x是函数ifunc自己的局部变量。
第三回合:如果在嵌套函数和函数(这里指包含嵌套函数的那个函数)中存在和全局变量同名的变量,如果直接使用,而不修改变量的值,那么这三个位置的变量使用的是同一个全局变量,如果在函数中修改了变量值,那么该变量会被标识为该函数的局部变量,嵌套函数直接使用时使用的是该函数的局部变量。如果在嵌套函数中修改同名变量的值,那么嵌套函数中的该变量会被标识为该嵌套函数的局部变量,它的修改不影响函数中同名变量和全局变量。
我们在嵌套函数中添加global关键字试试。
先不修改ifunc中x的值:
输出结果:
可以看出嵌套函数ifunc中的x是全局变量。
再修改一下ifunc中x的值试试:
输出结果:
可以看出嵌套函数中x是全局变量,但它的修改没有影响到func函数中的同名局部变量。
我们在前边已经发现在func函数中直接使用nonlocal关键字发生了报错,我们再试试在ifunc中使用nonlocal关键字:
输出结果:
可以看到nonlocal修饰后,ifunc中的x和func中的x是同一个变量,ifunc中修改x的值影响了func中的x(因为是一个变量),但并没有影响全局变量x。
再扩展一下:
在func函数中用global修饰x并修改ifunc中x的值,看看有什么变化:
输出结果:
我们再用nonlocal修饰一下ifunc函数中的x:
运行时发生报错,提示没有为ifunc中的x找到绑定。
第四回合:global可以在任何地方修饰变量,而且被global修饰的变量直接被标识为全局变量,对该变量修改会影响全局变量的值,但不影响函数中未被global修饰的同名变量(依然是局部变量),nonlocal只能在嵌套函数(可能还有其他的地方,我还没有检查)中使用,用于标识嵌套函数中的变量是包含该嵌套函数的函数中的同名变量,在嵌套函数中修改变量会影响函数中的变量。如果在函数中使用global修饰了变量,那么在嵌套函数中用nonlocal修饰同名变量会发生报错,因为nonlocal表示该变量在函数中已经定义,但检查时因为同名变量被global修饰为全局变量,所以不存在同名的局部变量,从而导致错误。
来源:https://blog.csdn.net/xcyansun/article/details/79672634
猜你喜欢
- SQL,数据分析岗的必备技能,你可以不懂Python,R,不懂可视化,不懂机器学习。但SQL,你必须懂。要不然领导让你跑个数据来汇.....
- 1提取 PDF 内容# pip install PyPDF2 安装 PyPDF2import PyPDF2from PyPDF2
- python遍历字符串中的每一个字符有4种方式:1. for in ;2.iter内置函数;3.内置函数range()或xrange();4
- 数据备份与还原第三篇,具体如下基础概念:备份,将当前已有的数据或记录另存一份;还原,将数据恢复到备份时的状态。为什么要进行数据的备份与还原?
- 前言PostgreSQL (也叫 Postgres)是一个自由的对象-关系数据库服务器(数据库管理系统),它在灵活的 BSD-风格许可证下发
- index()方法确定字符串str,如果起始索引beg和结束索引end在末尾给出了找到字符串或字符串的一个子串。这个方法与fin
- 我大概思考了下有如下几种方法可以解决: 1.在图片服务器上开通FTP,人为添加图片地址即可,但不方便,特别是在可视编辑器中看图还的多一部操作
- 我们肯定都很熟悉商品购物车这一功能,每当我们在某宝某东上购买商品的时候,看中了哪件商品,就会加入购物车中,最后结算。购物车这一功能,方便消费
- torch.optim的灵活使用详解1. 基本用法:要构建一个优化器Optimizer,必须给它一个包含参数的迭代器来优化,然后,我们可以指
- 在这篇文章中,我们会介绍如何用Python来搭建一个简单的推荐系统。本文使用的数据集是MovieLens数据集,该数据集由明尼苏达大学的Gr
- PyCharm是Python著名的Python集成开发环境(IDE)conda有Miniconda和Anaconda,前者应该是类似最小化版
- 起步上一篇 《Python 的枚举类型》 文末说有机会的话可以看看它的源码。那就来读一读,看看枚举的几个重要的特性是如何实现的。要想阅读这部
- 前言本文将深入研究 preg_replace /e 模式下的代码执行问题,其中包括 preg_replace 函数的执行过程分析、正则表达式
- 简单的并发控制利用 channel 的缓冲设定,我们就可以来实现并发的限制。我们只要在执行并发的同时,往一个带有缓冲的 chann
- 下面是BeforeInitialBind事件过程:<SCRIPT language=vbscript event=
- 本文实例讲述了Python实现手写一个类似django的web框架。分享给大家供大家参考,具体如下:用与django相似结构写一个web框架
- 当我们使用传统的 mysql_connect 、mysql_query方法来连接查询数据库时,如果过滤不严,就有SQL注入风险,导致网站被攻
- 一、功能实现对学生对个人信息的增删查改实现后台对所有学生信息的操作二、平台windows+pycharm(python开发工具)三、逻辑框图
- 闲言少叙,本文主要是想介绍一个Golang开发常见的一个问题。然而,此问题对于初学者来说却经常容易陷入坑中。问题我在写一段代码时,使用了Go
- 布局管理就是管理图形窗口中各个部件的位置和排列。图形窗口中的大量部件也需要通过布局管理,对部件进行整理分组、排列定位,才能使界面整齐有序、美