PYTHON 中使用 GLOBAL引发的一系列问题


Posted in Python onOctober 12, 2016

哪里出问题了

python 中,使用 global 会将全局变量设为本函数可用。同时,在函数内部访问变量会先本地再全局。

在嵌套函数中,使用 global 会产生不合常理的行为。

上代码:

In [96]: def x():
b = 12
def y():
global a,b
a = 1
b = 2
y()
print "b =",b
....: 
In [97]: a = 111
In [98]: del b
In [99]: x()
b = 12
In [100]: a
Out[100]: 1
In [101]: b
Out[101]: 2

而在函数 x() 中,没有用 global,此时的b使用本地。所以 print 会打印本地 b

为什么会打印 12 ?还有 In[101]的 b 为 2 该怎么解释?

y(),使用的 global 竟然没把 x() 的 b = 12 导进来。

在函数 y() 中,语句 global a,b 使a,b扩展为全局,所以,在最高层,就算没有 b(In[98]),也会产生 b(In[101])。

也就是说, global a,b ,会认为 a 和 b 是最外层的变量。

再试一下:

In [102]: def x():
b = 12
def y():
global a,b
a = 1
y() 
print "b =",b
.....: 
In [103]: a = 111
In [104]: del b
In [105]: x()
b = 12
In [106]: a
Out[106]: 1
In [107]: b
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-107-3b5d5c371295> in <module>()
----> 1 b
NameError: name 'b' is not defined

报错了! y() global b 后没赋值,顶层就没有 b。这说明,global 只是引入名称,并不做赋值等操作。

global 不会管变量存不存在,只导入名称,对该名称的操作会反应到 ‘最高层名称空间‘。

再来:

In [109]: a = 111
In [110]: del b
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-110-745f2abe7045> in <module>()
----> 1 del b
NameError: name 'b' is not defined
In [111]: def x():
b = 12
def y():
global a,b
a = 1
print b
y()
print "b =",b
.....: 
In [112]: x()
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-112-7354d77c61ac> in <module>()
----> 1 x()
<ipython-input-111-c05fc67a1e82> in x()
5 a = 1
6 print b
----> 7 y()
8 print "b =",b
9 
<ipython-input-111-c05fc67a1e82> in y()
4 global a,b
5 a = 1
----> 6 print b
7 y()
8 print "b =",b
NameError: global name 'b' is not defined

 这就确定了 内层y() 的 global 不会 导入 x() 的东西。

 那么,内层函数怎么使用正确的外层函数的变量呢?

解决内层函数参数传递问题

一、

首先,若只是取值,则不需要做任何处理。

In [119]: def x():
.....: a = 12
.....: def y():
.....: print a
.....: y()
.....: 
In [120]: x()
12
In [121]:

在 y() 中,一旦为 a 赋值,a 立马变内部变量。

In [121]: def x():
.....: a = 12
.....: def y():
.....: print "before a =",a
.....: a = 1
.....: print "then a =",a
.....: y()
.....: 
In [122]: x()
before a =---------------------------------------------------------------------------
UnboundLocalError Traceback (most recent call last)
<ipython-input-122-7354d77c61ac> in <module>()
----> 1 x()
<ipython-input-121-d8fbc0dba399> in x()
5 a = 1
6 print "then a =",a
----> 7 y()
8 
<ipython-input-121-d8fbc0dba399> in y()
2 a = 12
3 def y():
----> 4 print "before a =",a
5 a = 1
6 print "then a =",a
UnboundLocalError: local variable 'a' referenced before assignment

一旦在函数 y() 的某处给 a 赋值,则在赋值前,python 会认为 a 不存在。

同时发现 python2 的 print 会一个一个的 输出。鉴于此,我又在 python3 中试了,发现他是 一起输出。但这不是本文重点,折叠之。

In [7]: def x():
a = 1
def y():
print("before a=",a)
a = 10
print("then a=",a)
y()
...: 
In [8]: x()
---------------------------------------------------------------------------
UnboundLocalError Traceback (most recent call last)
<ipython-input-8-7354d77c61ac> in <module>()
----> 1 x()
<ipython-input-7-6e01e7317b24> in x()
a = 10
print("then a=",a)
----> 7 y()
<ipython-input-7-6e01e7317b24> in y()
a = 1
def y():
----> 4 print("before a=",a)
a = 10
print("then a=",a)
UnboundLocalError: local variable 'a' referenced before assignment

同时发现 python代码运行前 会先扫一遍代码的,而不是单纯的一行一行的执行。

同时发现返回 UnboundLocalError,而不是 NameError。注意到 'unbound‘,这是官方概念。用 'unbound‘ 来描述就是:global 会将顶层变量名称 绑定 到本地变量名称,同时变化,是为 '引用‘;python 检测到 a = 1时,意识到 a 是本地的,所以 在 a '指向一个对象‘(因为python变量均为引用),之前 ,调用 a 是非法 行为,但这种行为区别于于 NameError,就定义为 unbound local。

二、

使用 可变变量,如 list,dict

In [127]: def x():
.....: l = ["in msg"]
.....: def y():
.....: msg = l[0]
.....: print "msg =",msg
.....: l[:] = ["out msg"]
.....: y()
.....: print l[0]
.....: 
In [128]: x()
msg = in msg
out msg

没有报错,完美!

要注意 语句 l[:] = ["out msg"] ,使用切片赋值,否则,

In [129]: def x():
l = ["in msg"]
def y():
msg = l[0]
print "msg =",msg
l = ["out msg"]
y()
print l[0]
.....: 
In [130]: x()
---------------------------------------------------------------------------
UnboundLocalError Traceback (most recent call last)
<ipython-input-130-7354d77c61ac> in <module>()
----> 1 x()
<ipython-input-129-d44e750e285f> in x()
5 print "msg =",msg
6 l = ["out msg"]
----> 7 y()
8 print l[0]
9 
<ipython-input-129-d44e750e285f> in y()
2 l = ["in msg"]
3 def y():
----> 4 msg = l[0]
5 print "msg =",msg
6 l = ["out msg"]
UnboundLocalError: local variable 'l' referenced before assignment

又出 UnboundLocalError 了,因为 第六行代码 为 l 分配了 一个新的 list。

三、

利用参数传递。

In [136]: def x():
.....: a, b = 1, 2
.....: def y(a = a, b = b):
.....: a, b = 3, 4
.....: return a, b
.....: a, b = y()
.....: print a, b
.....: 
In [137]: x()
3 4

注意,不要在默认参数上放 list等可变对象。

以上所述是小编给大家介绍的PYTHON 中使用 GLOBAL引发的一系列问题,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
Python 绘图和可视化详细介绍
Feb 11 Python
Linux下python3.7.0安装教程
Jul 30 Python
Python中collections模块的基本使用教程
Dec 07 Python
pyqt5之将textBrowser的内容写入txt文档的方法
Jun 21 Python
基于sklearn实现Bagging算法(python)
Jul 11 Python
Django 权限认证(根据不同的用户,设置不同的显示和访问权限)
Jul 24 Python
python3调用windows dos命令的例子
Aug 14 Python
python实现的读取网页并分词功能示例
Oct 29 Python
Python如何使用OS模块调用cmd
Feb 27 Python
python中matplotlib实现随鼠标滑动自动标注代码
Apr 23 Python
Java byte数组操纵方式代码实例解析
Jul 22 Python
Python环境配置实现pip加速过程解析
Nov 27 Python
CentOS 6.X系统下升级Python2.6到Python2.7 的方法
Oct 12 #Python
shelve  用来持久化任意的Python对象实例代码
Oct 12 #Python
Pyhton中单行和多行注释的使用方法及规范
Oct 11 #Python
使用Python脚本实现批量网站存活检测遇到问题及解决方法
Oct 11 #Python
深入浅析ImageMagick命令执行漏洞
Oct 11 #Python
Zabbix实现微信报警功能
Oct 09 #Python
python 2.6.6升级到python 2.7.x版本的方法
Oct 09 #Python
You might like
我的论坛源代码(十)
2006/10/09 PHP
第六节--访问属性和方法
2006/11/16 PHP
JQuery 1.4 中的Ajax问题
2010/01/23 Javascript
javascript 45种缓动效果 非常酷
2011/06/28 Javascript
HTML5之lang属性与dir属性的详解
2013/06/19 Javascript
javascript实现原生ajax的几种方法介绍
2013/09/21 Javascript
javascript轻量级模板引擎juicer使用指南
2014/06/22 Javascript
Javascript限制网页只能在微信内置浏览器中访问
2014/11/09 Javascript
基于JS实现类似支付宝支付密码输入框
2016/09/02 Javascript
基于js实现二级下拉联动
2016/12/17 Javascript
jQuery中map函数的两种方式
2017/04/07 jQuery
基于JavaScript实现多级菜单效果
2017/07/25 Javascript
详细分析单线程JS执行问题
2017/11/22 Javascript
vue+swiper实现侧滑菜单效果
2017/12/28 Javascript
jquery实现动态添加附件功能
2018/10/23 jQuery
Nodejs 识别图片类型的方法
2019/08/15 NodeJs
使用pkg打包ThinkJS项目的方法步骤
2019/12/30 Javascript
JS实现炫酷轮播图
2020/11/15 Javascript
Python中使用中文的方法
2011/02/19 Python
使用Python的Treq on Twisted来进行HTTP压力测试
2015/04/16 Python
Python实现两款计算器功能示例
2017/12/19 Python
Python使用matplotlib绘制正弦和余弦曲线的方法示例
2018/01/06 Python
HTML5 语音搜索(淘宝店语音搜素)
2013/01/03 HTML / CSS
英国女性化妆品收纳和家具网站:Beautify
2019/12/07 全球购物
什么是聚集索引和非聚集索引
2012/01/17 面试题
Ejb技术面试题
2015/04/29 面试题
财务会计专业推荐信
2013/11/30 职场文书
网络编辑职责
2014/03/01 职场文书
信息技术毕业生自荐信范文
2014/03/13 职场文书
技术负责人任命书
2014/06/05 职场文书
2014党员干部四风问题对照检查材料思想汇报
2014/09/24 职场文书
民政局副局长民主生活会个人整改措施
2014/10/04 职场文书
退休教师追悼词
2015/06/23 职场文书
Spring Data JPA使用JPQL与原生SQL进行查询的操作
2021/06/15 Java/Android
Java实现简易的分词器功能
2021/06/15 Java/Android
JS高级程序设计之class继承重点详解
2022/07/07 Javascript