Python 中模块间全局变量的使用上的注意
最近用Python写代码,需要用到模块间的全局变量。
网上四处搜索,发现普遍做法是把全局变量放到一个独立的模块中,使用时,导入此全局变量模块即可。
但是在实际使用过程中发现了些小问题:在使用如下代码导入全局变量模块时,各个模块获取到的全局变量都是初始值。
from module import global_var
但是如果使用「模块名.全局变量名」来访问时,却又是正常的:
import module print module.global_var
为了弄清其中的原委,我写了个测试程序来仔细查看其中的细节:
1. import module
global_var.py
GLOBAL_VAR = [1, 2, 3]
m1.py
import global_var
import m2 print 'm1: before appending: ', id(global_var.GLOBAL_VAR), global_var.GLOBAL_VAR
global_var.GLOBAL_VAR.append('m1')
print 'm1: after appending: ', id(global_var.GLOBAL_VAR), global_var.GLOBAL_VAR print 'm1: before calling m2.append():', id(global_var.GLOBAL_VAR), global_var.GLOBAL_VAR
m2.append()
print 'm1: after calling m2.append(): ', id(global_var.GLOBAL_VAR), global_var.GLOBAL_VAR print '-----------------' print 'm1: before assigning: ', id(global_var.GLOBAL_VAR), global_var.GLOBAL_VAR
global_var.GLOBAL_VAR = ['m1']
print 'm1: after assigning: ', id(global_var.GLOBAL_VAR), global_var.GLOBAL_VAR print 'm1: before calling m2.assign():', id(global_var.GLOBAL_VAR), global_var.GLOBAL_VAR
m2.assign()
print 'm1: after calling m2.assign(): ', id(global_var.GLOBAL_VAR), global_var.GLOBAL_VAR
m2.py
import global_var def append():
print 'm2: before assiging: ', id(global_var.GLOBAL_VAR), global_var.GLOBAL_VAR
global_var.GLOBAL_VAR.append('m2')
print 'm2: after assiging: ', id(global_var.GLOBAL_VAR), global_var.GLOBAL_VAR def assign():
print 'm2: before assiging: ', id(global_var.GLOBAL_VAR), global_var.GLOBAL_VAR
global_var.GLOBAL_VAR = ['m2']
print 'm2: after assiging: ', id(global_var.GLOBAL_VAR), global_var.GLOBAL_VAR
运行结果:
Mac-pastgift:pytest pastgift$ python global_test_import/m1.py
m1: before appending: 4457308312 [1, 2, 3]
m1: after appending: 4457308312 [1, 2, 3, 'm1']
m1: before calling m2.append(): 4457308312 [1, 2, 3, 'm1']
m2: before assiging: 4457308312 [1, 2, 3, 'm1']
m2: after assiging: 4457308312 [1, 2, 3, 'm1', 'm2']
m1: after calling m2.append(): 4457308312 [1, 2, 3, 'm1', 'm2']
-----------------
m1: before assigning: 4457308312 [1, 2, 3, 'm1', 'm2']
m1: after assigning: 4457444848 ['m1']
m1: before calling m2.assign(): 4457444848 ['m1']
m2: before assiging: 4457444848 ['m1']
m2: after assiging: 4457308312 ['m2']
m1: after calling m2.assign(): 4457308312 ['m2']
在这种方式下,如果是改变对象本身的操作(append),各个模块内部的操作都是针对于同一个对象。
而赋值操作,虽然全局变量所指向的对象改变了,但是全局变量本身依然在各个模块内部能够正确访问,这正是我所希望的效果。
2. from module import GLOBAL_VAR
global_var.py
GLOBAL_VAR = [1, 2, 3]
m1.py
from global_var import GLOBAL_VAR
import m2 print 'm1: before appending: ', id(GLOBAL_VAR), GLOBAL_VAR
GLOBAL_VAR.append('m1')
print 'm1: after appending: ', id(GLOBAL_VAR), GLOBAL_VAR print 'm1: before calling m2.append():', id(GLOBAL_VAR), GLOBAL_VAR
m2.append()
print 'm1: after calling m2.append(): ', id(GLOBAL_VAR), GLOBAL_VAR print '-----------------' print 'm1: before assigning: ', id(GLOBAL_VAR), GLOBAL_VAR
GLOBAL_VAR = ['m1']
print 'm1: after assigning: ', id(GLOBAL_VAR), GLOBAL_VAR print 'm1: before calling m2.assign():', id(GLOBAL_VAR), GLOBAL_VAR
m2.assign()
print 'm1: after calling m2.assign(): ', id(GLOBAL_VAR), GLOBAL_VAR
m2.py
from global_var import GLOBAL_VAR def append():
global GLOBAL_VAR print 'm2: before assiging: ', id(GLOBAL_VAR), GLOBAL_VAR
GLOBAL_VAR.append('m2')
print 'm2: after assiging: ', id(GLOBAL_VAR), GLOBAL_VAR def assign():
global GLOBAL_VAR print 'm2: before assiging: ', id(GLOBAL_VAR), GLOBAL_VAR
GLOBAL_VAR = ['m2']
print 'm2: after assiging: ', id(GLOBAL_VAR), GLOBAL_VAR
运行结果:
Mac-pastgift:pytest pastgift$ python global_test_from_import/m1.py
m1: before appending: 4539998360 [1, 2, 3]
m1: after appending: 4539998360 [1, 2, 3, 'm1']
m1: before calling m2.append(): 4539998360 [1, 2, 3, 'm1']
m2: before assiging: 4539998360 [1, 2, 3, 'm1']
m2: after assiging: 4539998360 [1, 2, 3, 'm1', 'm2']
m1: after calling m2.append(): 4539998360 [1, 2, 3, 'm1', 'm2']
-----------------
m1: before assigning: [1, 2, 3, 'm1', 'm2']
m1: after assigning: 4540135112 ['m1']
m1: before calling m2.assign(): 4540135112 ['m1']
m2: before assiging: [1, 2, 3, 'm1', 'm2']
m2: after assiging: 4540135040 ['m2']
m1: after calling m2.assign(): 4540135112 ['m1']
这次,运行结果和上次略有不同。
改变对象本身的操作(append)和之前的例子一样,全局变量始终指向相同的对象。
但是赋值操作就比较奇怪了。注意标红部分,每个模块第一次获取到的这个「全局变量」都是相同id的对象。即使这个「全局变量」在其他模块中已经被重新赋值,但在本模块中依然指向的是最原始的id。
显然,这个算不上是「全局变量」了。
Python 中模块间全局变量的使用上的注意的更多相关文章
- Python中模块之os的功能介绍
Python中模块之os的功能介绍 1. os的变量 path 模块路径 方法:os.path 返回值:module 例如:print(os.path) >>> <module ...
- [python]关于在python中模块导入问题追加总结
[背景] 最近在写程序时,我使用的eclipse编辑器运行都没有问题,然后部署到自动化环境上却偏偏报找不到相应模块问题,现在对该问题在之前的贴子上追加总结 原帖子:[python]关于python中模 ...
- 查看python中模块的所有方法
查看python中模块的所有方法 安装的python模块,现将查看方法总结如下 一.CMD命令行下使用pydoc命令 在命令行下运行$ pydoc modules即可查看 二.在python交 ...
- [笔记]Python中模块互相调用的例子
python中模块互相调用容易出错,经常是在本地路径下工作正常,切换到其他路径来调用,就各种模块找不到了. 解决方法是通过__file__定位当前文件的真实路径,再通过sys.path.append( ...
- python中进程间通讯——文件锁之fcntl模块的使用
python 中给文件加锁——fcntl模块import fcntl 打开一个文件##当前目录下test文件要先存在,如果不存在会报错.或者以写的方式打开f = open('./test')对该文件加 ...
- Python中模块
模块 模块对我来说是什么 模块对我来说,感觉就像亲属或者朋友已经走过的路,他们已经趟过的浑水.掉过的坑.践行过的路线,全部提供给你,在你需要的时候请求帮助,借鉴他们的解决方法一样.都是为了方便走好人生 ...
- python 中 模块,包, 与常用模块
一 模块 模块:就是一组功能的集合体, 我们的程序可以直接导入模块来复用模块里的功能 导入方式 一般为 : import 模块名 在python中, 模块一般分为四个通用类别 1使用python编写. ...
- python中模块和包的概念
1.模块 一个.py文件就是一个模块.这个文件的名字是:模块名.py.由此可见在python中,文件名和模块名的差别只是有没有后缀.有后缀是文件名,没有后缀是模块名. 每个文件(每个模块)都是一个独立 ...
- python中模块的制作
1.import 模块名 2.from 模块名 import 类名(或方法名或全局变量) 3.from 模块名 import * 导入模块名下的所有类名,方法,全局变量 4.from 模块名 im ...
随机推荐
- 迷你template
JavaScript Micro-Templatinghttp://ejohn.org/blog/javascript-micro-templating/ //Simple JavaScript ...
- mac10.7安装xcode3.2.5和xcode4.2过程和方法
关于mac10.8安装xcoce3.2.5 五国或者不能成功的原因,看文章的最后部分. 大致浏览一下下面的内容,其实基本都是一样的,第一篇说明多个版本的xcode如何共存,后面的讲述如何安装xcode ...
- Hibernate学习笔记--------2.一多|多多的CRUD
一.一多关系 例如用户(Tb_User)和订单(Tb_Order)之间,一个用户对应了多个订单,多个订单对应一个用户. 除了基本的配置外,需要在用户类(单方)中添加订单的集合同样需要get/set方法 ...
- Gmail账户安全冰山一角
本文没有任何价值,只是一个事实的记录. 看到qq邮箱有个代理其他邮箱的功能,就好奇地输入了我的Gmail邮箱,结果代理不成功. 本来没care,后来gmail自己弹出来一封邮件. 后来我确认是本人所为 ...
- 解决闪光灯代码在Nexus5上面打不开的问题
参考:http://blog.csdn.net/cy524563/article/details/41545387 关键在于: int textureId = 0;whyCamera.setPrevi ...
- .Net 中表达式的转换
.Net 中表达式的转换 如: a>0 && (c>a || a <b ) || (a>b || c>1) 转换后 (((a > 0) a ...
- 猪满满 购物APP
猪满满是专注“省钱,赚钱”的购物App,使用自定义tabar分为四大类,分别是首页,超返,发现,我的. 首页:使用UItableview,自定义cell展示商品. 超返:自定义Button分为综合,返 ...
- myeclipse的新建severlet不见解决方法
点击myeclipse中的window菜单里面选择myeclipse java Enterprise 选项就可以恢复到默认.
- linux系统文件属性
1 硬链接概念 硬链接是指通过索引节点(Inode)来进行链接,在Linux(ext2,ext3)文件系统中,保存在磁盘分区中的文件不管是什么类型都会给它分配一个编号,这个编号被称为索引节点编号(I ...
- Oracle笔记(三)单行函数
-函数 函数像一个黑盒子一样(看不到里边的构造),有参数返回值,可以为我们完成一定的功能. -单行 这种函数会对结果中的每一行计算一次,每行返回一个结果,单行概念区别于分组函数. 单行函数主要分为以下 ...