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 相关文章推荐
python实现的各种排序算法代码
Mar 04 Python
Python生成验证码实例
Aug 21 Python
Python numpy生成矩阵、串联矩阵代码分享
Dec 04 Python
python3 pandas 读取MySQL数据和插入的实例
Apr 20 Python
python 匹配url中是否存在IP地址的方法
Jun 04 Python
详解Python的数据库操作(pymysql)
Apr 04 Python
Python爬取数据保存为Json格式的代码示例
Apr 09 Python
用python中的matplotlib绘制方程图像代码
Nov 21 Python
python enumerate内置函数用法总结
Jan 07 Python
tensorflow对图像进行拼接的例子
Feb 05 Python
Python使用struct处理二进制(pack和unpack用法)
Nov 12 Python
Python可视化神器pyecharts绘制地理图表
Jul 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
开源SNS系统-ThinkSNS
2008/05/18 PHP
php防止恶意刷新与刷票的方法
2014/11/21 PHP
php打印输出棋盘的实现方法
2014/12/23 PHP
WordPress的主题编写中获取头部模板和底部模板
2015/12/28 PHP
yii2 commands模式以及配置crontab定时任务的方法
2017/08/19 PHP
js 日期转换成中文格式的函数
2009/07/07 Javascript
利用location.hash实现跨域iframe自适应
2010/05/04 Javascript
JQuery FlexiGrid的asp.net完美解决方案 dotNetFlexGrid-.Net原生的异步表格控件
2010/09/12 Javascript
jquery $.ajax各个事件执行顺序
2010/10/15 Javascript
JavaScript实现拼音排序的方法
2012/11/20 Javascript
用javascript为页面添加天气显示实现思路及代码
2013/12/02 Javascript
jquery设置text的值示例(设置文本框 DIV 表单值)
2014/01/06 Javascript
javascript文件中引用依赖的js文件的方法
2014/03/17 Javascript
JavaScript也谈内存优化
2014/06/06 Javascript
前端微信支付js代码
2016/07/25 Javascript
jquery css实现邮箱自动补全
2016/11/14 Javascript
BootStrap Table对前台页面表格的支持实例讲解
2016/12/22 Javascript
JavaScript实现按键精灵的原理分析
2017/02/21 Javascript
jQuery获取table表中的td标签(实例讲解)
2017/07/28 jQuery
js实现拖拽上传图片功能
2017/08/01 Javascript
JS匿名函数和匿名自执行函数概念与用法分析
2018/03/16 Javascript
手挽手带你学React之React-router4.x的使用
2019/02/14 Javascript
小程序实现投票进度条
2019/11/20 Javascript
python实现给数组按片赋值的方法
2015/07/28 Python
Python入门_浅谈字符串的分片与索引、字符串的方法
2017/05/16 Python
Python 高级专用类方法的实例详解
2017/09/11 Python
教你用一行Python代码实现并行任务(附代码)
2018/02/02 Python
使用python获取csv文本的某行或某列数据的实例
2018/04/03 Python
Python序列循环移位的3种方法推荐
2018/04/09 Python
解决python3 网络请求路径包含中文的问题
2018/05/10 Python
python GUI库图形界面开发之PyQt5不规则窗口实现与显示GIF动画的详细方法与实例
2020/03/09 Python
Django3中的自定义用户模型实例详解
2020/08/23 Python
python 调用Google翻译接口的方法
2020/12/09 Python
澳大利亚最大的护发和护肤品购物网站:RY
2019/12/26 全球购物
2014年仓库工作总结
2014/11/20 职场文书
2016年教师政治思想表现评语
2015/12/02 职场文书