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中的exec、eval使用实例
Sep 23 Python
跟老齐学Python之关于类的初步认识
Oct 11 Python
Python入门教程之if语句的用法
May 14 Python
Python实现基于C/S架构的聊天室功能详解
Jul 07 Python
Python求均值,方差,标准差的实例
Jun 29 Python
python实现从本地摄像头和网络摄像头截取图片功能
Jul 11 Python
Python3 批量扫描端口的例子
Jul 25 Python
python自动发微信监控报警
Sep 06 Python
python编写猜数字小游戏
Oct 06 Python
Keras使用ImageNet上预训练的模型方式
May 23 Python
Python实现树莓派摄像头持续录像并传送到主机的步骤
Nov 30 Python
Python实现socket库网络通信套接字
Jun 04 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
递归删除一个节点以及该节点下的所有节点示例
2014/03/19 PHP
php使用yield对性能提升的测试实例分析
2019/09/19 PHP
laravel框架数据库配置及操作数据库示例
2019/10/10 PHP
jquery仿京东导航/仿淘宝商城左侧分类导航下拉菜单效果
2013/04/24 Javascript
javascript强大的日期函数代码分享
2013/09/04 Javascript
Knockout text绑定DOM的使用方法
2013/11/15 Javascript
jquery 获取dom固定元素 添加样式的简单实例
2014/02/04 Javascript
node.js中的url.format方法使用说明
2014/12/10 Javascript
javascript带回调函数的异步脚本载入方法实例分析
2015/07/02 Javascript
轻松学习jQuery插件EasyUI EasyUI创建树形菜单
2015/11/30 Javascript
jQuery常见的选择器及用法介绍
2016/12/20 Javascript
Bootstrap输入框组件简单实现代码
2017/03/06 Javascript
Three.js如何用轨迹球插件(trackball)增加对模型的交互功能详解
2017/09/25 Javascript
解决vue打包之后静态资源图片失效的问题
2018/02/21 Javascript
小程序实现悬浮搜索框
2019/07/12 Javascript
Layui实现带查询条件的分页
2019/07/27 Javascript
vue2.x 通过后端接口代理,获取qq音乐api的数据示例
2019/10/30 Javascript
Vue中点击active并第一个默认选中功能的实现
2020/02/24 Javascript
jquery实现轮播图特效
2020/04/12 jQuery
基于Vue中的父子传值问题解决
2020/07/27 Javascript
在Python中使用模块的教程
2015/04/27 Python
Python如何快速实现分布式任务
2017/07/06 Python
Python操作csv文件实例详解
2017/07/31 Python
对python中return和print的一些理解
2017/08/18 Python
python实现DEM数据的阴影生成的方法
2019/07/23 Python
python scipy卷积运算的实现方法
2019/09/16 Python
Python使用Tkinter实现滚动抽奖器效果
2020/01/06 Python
基于python实现生成指定大小txt文档
2020/07/20 Python
Python 多进程、多线程效率对比
2020/11/19 Python
Free People中国官网:波西米亚风格女装服饰
2016/08/30 全球购物
英国派对礼服和连衣裙购物网站:TFNC London
2018/07/07 全球购物
构造方法和其他方法的区别
2016/04/26 面试题
医院后勤自我鉴定
2013/10/13 职场文书
诚信考试标语
2014/06/24 职场文书
PyQt5爬取12306车票信息程序的实现
2021/05/14 Python
Python办公自动化PPT批量转换操作
2021/09/15 Python