Python中关键字global和nonlocal的区别详解


Posted in Python onSeptember 03, 2018

前言

终于下定决心学习Python了。既然从头开始,就需要认认真真。

首先需要说的是,我是初学Python,这篇文章只是用于展示global和nonlocal关键字的区别,是很简单的知识点,如果你已经学过,可以绕道。因为不经常写博客,而且是个Python小白,所以内容有些??隆!!?/p>

两个关键词都用于允许在一个局部作用域中使用外层的变量。

  • global 表示将变量声明为全局变量
  • nonlocal 表示将变量声明为外层变量(外层函数的局部变量,而且不能是全局变量)

注意:我使用的是Python3.6.3,可能和Python2有不同的地方,并未确认。

考虑到文章比较??拢?劝呀崧厶?隼矗?苊饫朔汛蠹业氖奔洌?/strong>

第一,两者的功能不同。global关键字修饰变量后标识该变量是全局变量,对该变量进行修改就是修改全局变量,而nonlocal关键字修饰变量后标识该变量是上一级函数中的局部变量,如果上一级函数中不存在该局部变量,nonlocal位置会发生错误(最上层的函数使用nonlocal修饰变量必定会报错)。

第二,两者使用的范围不同。global关键字可以用在任何地方,包括最上层函数中和嵌套函数中,即使之前未定义该变量,global修饰后也可以直接使用,而nonlocal关键字只能用于嵌套函数中,并且外层函数中定义了相应的局部变量,否则会发生错误(见第一)。

接下来是得到结论的过程,有兴趣的可以浏览一下。

我们先来看一个代码片段,看看默认情况下输出结果是什么(不敢恭维CSDN显示代码的格式,这里使用图片,如果要验证,得麻烦各位动动指头了)。

Python中关键字global和nonlocal的区别详解

输出结果:

Python中关键字global和nonlocal的区别详解

上面的代码片段中没有使用global或nonlocal关键字,是为了看一下默认情况下的输出结果。

可以看到变量x在三次输出中是同一个变量(值相同,地址也相同),都是全局变量,在print函数中使用三个参数是为了方便识别变量,第一个参数是print运行的位置,第二个参数是变量x保存的值,第三个参数是变量x保存的值的地址(这个有待考证)。

如果我们在func函数中修改x的值呢?

Python中关键字global和nonlocal的区别详解

输出结果:

Python中关键字global和nonlocal的区别详解

可以看到func函数中x的值和地址都变了,但没有影响函数外边的x的值和地址(main1和main2的数据相同)。所以func函数内的x变量和函数外的x变量是两个变量,而func内的x变量是局部变量,修改它的值不影响全局变量。

第一回合:在函数内部使用了与全局变量同名的变量,如果不对该变量赋值(修改变量),那么该变量就是全局变量,如果对该变量进行赋值,那么该变量就是局部变量。

如果我们想在func函数内修改全局变量x呢?我们先试试用global(全局)。

Python中关键字global和nonlocal的区别详解

运行后报错,提示语法错误。原来global修饰变量时不能直接赋值,修改为如下:

Python中关键字global和nonlocal的区别详解

运行结果:

Python中关键字global和nonlocal的区别详解

可以看到main1位置的x和func内部func1位置的x是同一个值,但和func内部的func2以及main2位置的x不一样了,反而是main2处的x和func内部的x变量是同一个。

第二回合:global关键字修饰函数内部变量后标志其是全局变量(这里不能说global将x从局部变量改为了全局变量),如果用global修饰函数内的变量,必须在使用该变量前进行修饰(否则会发生变量未定义的错误,请你自己尝试一下)。

我们试试nonlocal关键字呢?

Python中关键字global和nonlocal的区别详解

报错了,无法使用nonlocal关键字。

接下来我们看看怎样使用nonlocal关键字。

我们先添加一个嵌套函数:

Python中关键字global和nonlocal的区别详解

输出结果:

Python中关键字global和nonlocal的区别详解

可以看到嵌套函数内默认使用的也是全局变量。我们在func函数中修改一下x的值试试。

Python中关键字global和nonlocal的区别详解

输出结果:

Python中关键字global和nonlocal的区别详解

可以看到在func函数中修改x后,x被标识成局部变量,它的改变并没有影响全局变量x,但嵌套函数ifunc中的x受到了影响,显示ifunc中的x是func函数中的局部变量。

我们再继续修改一下ifunc中x的值。

Python中关键字global和nonlocal的区别详解

输出结果:

Python中关键字global和nonlocal的区别详解

可以看到在ifunc修改x的之后即没有影响func中的局部变量x,也没有影响全局变量x,ifunc中的x是函数ifunc自己的局部变量。

第三回合:如果在嵌套函数和函数(这里指包含嵌套函数的那个函数)中存在和全局变量同名的变量,如果直接使用,而不修改变量的值,那么这三个位置的变量使用的是同一个全局变量,如果在函数中修改了变量值,那么该变量会被标识为该函数的局部变量,嵌套函数直接使用时使用的是该函数的局部变量。如果在嵌套函数中修改同名变量的值,那么嵌套函数中的该变量会被标识为该嵌套函数的局部变量,它的修改不影响函数中同名变量和全局变量。

我们在嵌套函数中添加global关键字试试。

先不修改ifunc中x的值:

Python中关键字global和nonlocal的区别详解

输出结果:

Python中关键字global和nonlocal的区别详解

可以看出嵌套函数ifunc中的x是全局变量。

再修改一下ifunc中x的值试试:

Python中关键字global和nonlocal的区别详解

输出结果:

Python中关键字global和nonlocal的区别详解

可以看出嵌套函数中x是全局变量,但它的修改没有影响到func函数中的同名局部变量。

我们在前边已经发现在func函数中直接使用nonlocal关键字发生了报错,我们再试试在ifunc中使用nonlocal关键字:

Python中关键字global和nonlocal的区别详解

输出结果:

Python中关键字global和nonlocal的区别详解

可以看到nonlocal修饰后,ifunc中的x和func中的x是同一个变量,ifunc中修改x的值影响了func中的x(因为是一个变量),但并没有影响全局变量x。

再扩展一下:

在func函数中用global修饰x并修改ifunc中x的值,看看有什么变化:

Python中关键字global和nonlocal的区别详解

输出结果:

Python中关键字global和nonlocal的区别详解

我们再用nonlocal修饰一下ifunc函数中的x:

Python中关键字global和nonlocal的区别详解

运行时发生报错,提示没有为ifunc中的x找到绑定。

第四回合:global可以在任何地方修饰变量,而且被global修饰的变量直接被标识为全局变量,对该变量修改会影响全局变量的值,但不影响函数中未被global修饰的同名变量(依然是局部变量),nonlocal只能在嵌套函数(可能还有其他的地方,我还没有检查)中使用,用于标识嵌套函数中的变量是包含该嵌套函数的函数中的同名变量,在嵌套函数中修改变量会影响函数中的变量。如果在函数中使用global修饰了变量,那么在嵌套函数中用nonlocal修饰同名变量会发生报错,因为nonlocal表示该变量在函数中已经定义,但检查时因为同名变量被global修饰为全局变量,所以不存在同名的局部变量,从而导致错误。

总结:

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
在MAC上搭建python数据分析开发环境
Jan 26 Python
使用Nginx+uWsgi实现Python的Django框架站点动静分离
Mar 21 Python
Python按行读取文件的实现方法【小文件和大文件读取】
Sep 19 Python
python实现远程通过网络邮件控制计算机重启或关机
Feb 22 Python
下载python中Crypto库报错:ModuleNotFoundError: No module named ‘Crypto’的解决
Apr 23 Python
替换python字典中的key值方法
Jul 06 Python
python如何查看微信消息撤回
Nov 27 Python
python json.loads兼容单引号数据的方法
Dec 19 Python
Python设计模式之模板方法模式实例详解
Jan 17 Python
python贪吃蛇游戏代码
Apr 18 Python
如何用用Python将地址标记在地图上
Feb 07 Python
python数据抓取3种方法总结
Feb 07 Python
python leetcode 字符串相乘实例详解
Sep 03 #Python
Python模拟自动存取款机的查询、存取款、修改密码等操作
Sep 02 #Python
Python实现多级目录压缩与解压文件的方法
Sep 01 #Python
Python实现压缩文件夹与解压缩zip文件的方法
Sep 01 #Python
Python pymongo模块常用操作分析
Sep 01 #Python
Python实现提取XML内容并保存到Excel中的方法
Sep 01 #Python
python使用webdriver爬取微信公众号
Aug 31 #Python
You might like
虹吸壶煮咖啡26个注意事项
2021/03/03 冲泡冲煮
用js进行url编码后用php反解以及用php实现js的escape功能函数总结
2010/02/08 PHP
浅析ThinkPHP的模板输出功能
2014/07/01 PHP
PHP爬虫之百万级别知乎用户数据爬取与分析
2016/01/22 PHP
在Laravel中使用DataTables插件的方法
2018/05/29 PHP
php封装实现钉钉机器人报警接口的示例代码
2020/08/08 PHP
formStorage 基于jquery的一个插件(存储表单中元素的状态到本地)
2012/01/20 Javascript
浅析JavaScript中的隐式类型转换
2013/12/05 Javascript
AngularJS基础知识笔记之过滤器
2015/05/10 Javascript
js实现字符串和数组之间相互转换操作
2016/01/12 Javascript
AngularJS基础 ng-keypress 指令简单示例
2016/08/02 Javascript
AngularJS指令用法详解
2016/11/02 Javascript
js实现登录验证码
2016/12/22 Javascript
详解50行代码,Node爬虫练手项目
2019/04/22 Javascript
微信小程序webview与h5通过postMessage实现实时通讯的实现
2019/08/20 Javascript
jQuery实现聊天对话框
2020/02/08 jQuery
Python 条件判断的缩写方法
2008/09/06 Python
python根据时间生成mongodb的ObjectId的方法
2015/03/13 Python
python 实现将txt文件多行合并为一行并将中间的空格去掉方法
2018/12/20 Python
Django如何将URL映射到视图
2019/07/29 Python
Django 框架模型操作入门教程
2019/11/05 Python
Python 多线程C段扫描、检测 Ping扫描脚本的实现
2020/09/03 Python
华丽的手绘陶瓷:MacKenzie-Childs
2017/02/04 全球购物
如何选择使用结构还是类
2014/05/30 面试题
优秀的计算机专业求职信范文
2013/12/27 职场文书
长安大学毕业生自我鉴定
2014/01/17 职场文书
2014年幼儿园元旦活动方案
2014/02/13 职场文书
领导批评与自我批评范文
2014/10/16 职场文书
2014年四风个人对照检查及整改措施
2014/10/28 职场文书
保安辞职信范文
2015/02/28 职场文书
医务人员医德考评自我评价
2015/03/03 职场文书
清明节寄语2015
2015/03/23 职场文书
实施意见格式范本
2015/06/05 职场文书
2016年感恩节寄语
2015/12/07 职场文书
Python实现位图分割的效果
2021/11/20 Python
PostgreSQL并行计算算法及参数强制并行度设置方法
2022/04/07 PostgreSQL