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 相关文章推荐
linux下python抓屏实现方法
May 22 Python
django实现分页的方法
May 26 Python
一步步解析Python斗牛游戏的概率
Feb 12 Python
Python中eval带来的潜在风险代码分析
Dec 11 Python
对numpy 数组和矩阵的乘法的进一步理解
Apr 04 Python
设置python3为默认python的方法
Oct 31 Python
python 监听salt job状态,并任务数据推送到redis中的方法
Jan 14 Python
基于Python实现迪杰斯特拉和弗洛伊德算法
May 27 Python
python tkinter实现屏保程序
Jul 30 Python
pytorch实现特殊的Module--Sqeuential三种写法
Jan 15 Python
自定义Django Form中choicefield下拉菜单选取数据库内容实例
Mar 13 Python
详解PyQt5中textBrowser显示print语句输出的简单方法
Aug 07 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
php 404错误页面实现代码
2009/06/22 PHP
php多层数组与对象的转换实例代码
2013/08/05 PHP
利用PHP_XLSXWriter代替PHPExcel的方法示例
2017/07/16 PHP
PHP convert_uudecode()函数讲解
2019/02/14 PHP
mongodb和php的用法详解
2019/03/25 PHP
js可突破windows弹退效果代码
2008/08/09 Javascript
弹出窗口并且此窗口带有半透明的遮罩层效果
2014/03/13 Javascript
如何编写高质量JS代码(续)
2015/02/25 Javascript
JS+CSS实现的拖动分页效果实例
2015/05/11 Javascript
js过滤HTML标签完整实例
2015/11/26 Javascript
Jquery元素追加和删除的实现方法
2016/05/24 Javascript
js和jQuery以及easyui实现对下拉框的指定赋值方法
2018/01/23 jQuery
小程序实现分类页
2019/07/12 Javascript
[19:54]夜魇凡尔赛茶话会 第一期02:看图识人
2021/03/11 DOTA
python中的闭包用法实例详解
2015/05/05 Python
浅析Python的web.py框架中url的设定方法
2016/07/11 Python
Python中不同进制的语法及转换方法分析
2016/07/27 Python
django主动抛出403异常的方法详解
2019/01/04 Python
numpy.random模块用法总结
2019/05/27 Python
利用pyuic5将ui文件转换为py文件的方法
2019/06/19 Python
Python 循环终止语句的三种方法小结
2019/06/24 Python
python从list列表中选出一个数和其对应的坐标方法
2019/07/20 Python
Pytorch高阶OP操作where,gather原理
2020/04/30 Python
Lookfantastic法国官网:英国知名美妆购物网站
2017/10/28 全球购物
市场营销专科应届生求职信
2013/11/24 职场文书
班队活动设计方案
2014/01/30 职场文书
中学生自我鉴定
2014/02/04 职场文书
促销活动总结
2014/04/28 职场文书
卫生厅领导班子党的群众路线教育实践活动整改措施
2014/09/20 职场文书
营销与策划实训报告
2014/11/05 职场文书
药店营业员岗位职责
2015/04/14 职场文书
公司员工违纪检讨书
2015/05/05 职场文书
上课讲话检讨书范文
2015/05/07 职场文书
土木工程毕业答辩开场白
2015/05/29 职场文书
签证工作证明模板
2015/06/15 职场文书
uwsgi+nginx代理Django无法访问静态资源的解决
2021/05/10 Servers