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的描述符(descriptor)、装饰器(property)造成的一个无限递归问题分享
Jul 09 Python
Python selenium 父子、兄弟、相邻节点定位方式详解
Sep 15 Python
一个基于flask的web应用诞生 记录用户账户登录状态(6)
Apr 11 Python
Python算法之求n个节点不同二叉树个数
Oct 27 Python
Python数据结构与算法之二叉树结构定义与遍历方法详解
Dec 12 Python
Python 25行代码实现的RSA算法详解
Apr 10 Python
Python爬虫文件下载图文教程
Dec 23 Python
Python multiprocessing多进程原理与应用示例
Feb 28 Python
Python函数参数类型及排序原理总结
Dec 19 Python
Django models filter筛选条件详解
Mar 16 Python
Python decimal模块使用方法详解
Jun 08 Python
Pytorch 实现变量类型转换
May 17 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的ajax框架xajax入门与试用介绍
2010/12/19 PHP
利用PHP生成静态HTML文档的原理
2012/10/29 PHP
php编程每天必学之表单验证
2016/03/01 PHP
多个iframe自动调整大小的问题
2006/09/18 Javascript
javascript 操作文件 实现方法小结
2009/07/02 Javascript
js浮动图片的动态效果
2013/07/10 Javascript
JS简单的图片放大缩小的两种方法
2013/11/11 Javascript
JavaScript实现为input与textarea自定义hover,focus效果的方法
2015/08/21 Javascript
js jquery获取当前元素的兄弟级 上一个 下一个元素
2015/09/01 Javascript
js解决movebox移动问题
2016/03/29 Javascript
详解JavaScript实现设计模式中的适配器模式的方法
2016/05/18 Javascript
Vue.js每天必学之过滤器与自定义过滤器
2016/09/07 Javascript
bootstrap table复杂操作代码
2016/11/01 Javascript
利用jQuery插件imgAreaSelect实现图片上传裁剪(放大缩小)
2016/12/02 Javascript
详解webpack解惑:require的五种用法
2017/06/09 Javascript
VUE实现一个分页组件的示例
2017/09/13 Javascript
Vue 路由切换时页面内容没有重新加载的解决方法
2018/09/01 Javascript
仅用50行代码实现一个Python编写的计算器的教程
2015/04/17 Python
Python冒泡排序注意要点实例详解
2016/09/09 Python
对pandas处理json数据的方法详解
2019/02/08 Python
django 快速启动数据库客户端程序的方法示例
2019/08/16 Python
python 瀑布线指标编写实例
2020/06/03 Python
Tensorflow tensor 数学运算和逻辑运算方式
2020/06/30 Python
基于python实现监听Rabbitmq系统日志代码示例
2020/11/28 Python
为2021年的第一场雪锦上添花:用matplotlib绘制雪花和雪景
2021/01/05 Python
解决pycharm 格式报错tabs和space不一致问题
2021/02/26 Python
德国价格合理的品牌商品购物网站:averdo
2019/03/21 全球购物
什么是makefile? 如何编写makefile?
2012/08/08 面试题
煤矿安全生产责任书
2014/04/15 职场文书
目标责任书格式
2014/07/28 职场文书
四风对照检查材料思想汇报
2014/09/20 职场文书
党支部班子“四风”问题自我剖析材料
2014/09/28 职场文书
2014年计划生育工作总结
2014/11/14 职场文书
海上钢琴师的观后感
2015/06/11 职场文书
初中生物教学反思
2016/02/20 职场文书
Go语言并发编程 sync.Once
2021/10/16 Golang