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 相关文章推荐
精确查找PHP WEBSHELL木马的方法(1)
Apr 12 Python
使用Python的Tornado框架实现一个简单的WebQQ机器人
Apr 24 Python
python实现自动发送邮件发送多人、群发、多附件的示例
Jan 23 Python
Python 绘图库 Matplotlib 入门教程
Apr 19 Python
安装docker-compose的两种最简方法
Jul 30 Python
python 模拟银行转账功能过程详解
Aug 06 Python
python数据化运营的重要意义
Nov 25 Python
Python如何获取Win7,Win10系统缩放大小
Jan 10 Python
Python读入mnist二进制图像文件并显示实例
Apr 24 Python
Python分析最近大火的网剧《隐秘的角落》
Jul 02 Python
python读取pdf格式文档的实现代码
Apr 01 Python
如何理解及使用Python闭包
Jun 01 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
玩转虚拟域名◎+ .
2006/10/09 PHP
header()函数使用说明
2006/11/23 PHP
php 论坛采集程序 模拟登陆,抓取页面 实现代码
2009/07/09 PHP
Discuz 6.0+ 批量注册用户名
2009/09/13 PHP
web目录下不应该存在多余的程序(安全考虑)
2012/05/09 PHP
PHP数学运算函数大汇总(经典值得收藏)
2016/04/01 PHP
一些不错的js函数ajax
2008/08/20 Javascript
jquery 表单下所有元素的隐藏
2009/07/25 Javascript
Javascript setInterval的两种调用方法(实例讲解)
2013/11/29 Javascript
JavaScript结合AJAX_stream实现流式显示
2015/01/08 Javascript
JS实现带圆弧背景渐变效果的导航菜单代码
2015/10/13 Javascript
jQuery删除当前节点元素
2016/12/07 Javascript
JavaScript字符集编码与解码详谈
2017/02/02 Javascript
深究AngularJS中ng-drag、ng-drop的用法
2017/06/12 Javascript
angularJs使用ng-repeat遍历后选中某一个的方法
2018/09/30 Javascript
微信小程序实现页面浮动导航
2020/01/08 Javascript
使用 Jest 和 Supertest 进行接口端点测试实例详解
2020/04/25 Javascript
vue递归获取父元素的元素实例
2020/08/07 Javascript
Vue实现指令式动态追加小球动画组件的步骤
2020/12/18 Vue.js
使用python Django做网页
2013/11/04 Python
调试Python程序代码的几种方法总结
2015/04/28 Python
使用Python求解最大公约数的实现方法
2015/08/20 Python
python中import学习备忘笔记
2017/01/24 Python
使用Python3制作TCP端口扫描器
2017/04/17 Python
Python使用requests及BeautifulSoup构建爬虫实例代码
2018/01/24 Python
解决python升级引起的pip执行错误的问题
2018/06/12 Python
python生成特定分布数的实例
2019/12/05 Python
Python 字符串池化的前提
2020/07/03 Python
Python用dilb提取照片上人脸的示例
2020/10/26 Python
python中time.ctime()实例用法
2021/02/03 Python
美国首屈一指的礼品篮供应商:GiftTree
2018/01/06 全球购物
DC Shoes荷兰官方网站:美国极限运动品牌
2019/10/22 全球购物
解释一下ArrayList Vector和LinkedList的实现和区别
2013/04/26 面试题
创业计划书之干洗店
2019/09/10 职场文书
Nginx服务器添加Systemd自定义服务过程解析
2021/03/31 Servers
CSS完成视差滚动效果
2021/04/27 HTML / CSS