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 相关文章推荐
Windows下为Python安装Matplotlib模块
Nov 06 Python
python批量修改图片大小的方法
Jul 24 Python
使用Python实现一个栈判断括号是否平衡
Aug 23 Python
python实现简单名片管理系统
Nov 30 Python
python感知机实现代码
Jan 18 Python
Numpy之random函数使用学习
Jan 29 Python
django-allauth入门学习和使用详解
Jul 03 Python
python2使用bs4爬取腾讯社招过程解析
Aug 14 Python
Python3常见函数range()用法详解
Dec 30 Python
基于python 等频分箱qcut问题的解决
Mar 03 Python
教你用Python写一个植物大战僵尸小游戏
Apr 25 Python
Python scrapy爬取起点中文网小说榜单
Jun 13 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
php session处理的定制
2009/03/16 PHP
PHP生成唯一的促销/优惠/折扣码(附源码)
2012/12/28 PHP
PHP解析html类库simple_html_dom的转码bug
2014/05/22 PHP
zend框架实现支持sql server的操作方法
2016/12/08 PHP
laravel 5.4中实现无限级分类的方法示例
2017/07/27 PHP
Thinkphp5.0 框架视图view的比较标签用法分析
2019/10/12 PHP
IE bug table元素的innerHTML
2010/01/11 Javascript
javascript 隔行换色函数代码
2010/10/24 Javascript
jquery.boxy弹出框(后隔N秒后自动隐藏/自动跳转)
2013/01/15 Javascript
Jquery仿IGoogle实现可拖动窗口示例代码
2014/08/22 Javascript
学习JavaScript设计模式之状态模式
2016/01/08 Javascript
基于JavaScript实现瀑布流布局(二)
2016/01/26 Javascript
js判断图片加载完成后获取图片实际宽高的方法
2016/02/25 Javascript
实例详解ECMAScript5中新增的Array方法
2016/04/05 Javascript
angular动态删除ng-repaeat添加的dom节点的方法
2017/07/20 Javascript
Angular 如何使用第三方库的方法
2018/04/18 Javascript
nodejs实现日志读取、日志查找及日志刷新的方法分析
2019/05/20 NodeJs
vue-cli脚手架打包静态资源请求出错的原因与解决
2019/06/06 Javascript
微信小程序实现点击图片放大预览
2019/10/21 Javascript
vue请求服务器数据后绑定不上的解决方法
2019/10/30 Javascript
vue 遮罩层阻止默认滚动事件操作
2020/07/28 Javascript
Python计算回文数的方法
2015/03/11 Python
Python 创建子进程模块subprocess详解
2015/04/08 Python
Python字符串详细介绍
2015/05/09 Python
Python爬虫beautifulsoup4常用的解析方法总结
2019/02/25 Python
Python 20行简单实现有道在线翻译的详解
2019/05/15 Python
python飞机大战pygame游戏框架搭建操作详解
2019/12/17 Python
给幼儿园老师的表扬信
2014/01/19 职场文书
机械设计毕业生自荐信
2014/02/02 职场文书
残疾人小组计划书
2014/04/27 职场文书
写给父母的感谢信
2015/01/22 职场文书
会计岗位工作总结
2015/08/12 职场文书
初中班主任培训心得体会
2016/01/07 职场文书
导游词之日本富士山
2020/01/06 职场文书
Nginx报错104:Connection reset by peer问题的解决及分析
2022/07/23 Servers
go goth封装第三方认证库示例详解
2022/08/14 Golang