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 ...
随机推荐
- 在Struts2中使用ValueStack、ActionContext、ServletContext、request、session等 .
笔者不知道该用哪个词来形容ValueStack.ActionContext等可以在Struts2中用来存放数据的类.这些类使用的范围不同,得到的方法也不同,下面就来一一介绍. 声明:本文参考Strut ...
- mysql优化--博森瑞
http://blog.itpub.net/28916011/viewspace-1758440/ 现在说一下mysql的内存和I/O方面的两个特点. 一. mysql内存特点: 1. 也有全局内存 ...
- 阿里封神谈hadoop学习之路
阿里封神谈hadoop学习之路 封神 2016-04-14 16:03:51 浏览3283 评论3 发表于: 阿里云E-MapReduce >> 开源大数据周刊 hadoop 学生 s ...
- java RSA加密解密--转载
原文地址:http://www.blogjava.net/icewee/archive/2012/05/19/378570.html 该工具类中用到了BASE64,需要借助第三方类库:javabase ...
- MSP430常见问题之工作模式和功耗类
Q1:1,MSP430进入LP 模式后,CPU 停止运行,那么,进入中断执行退出后,由于SR的恢复,导致还处于LP 模式,是否意味着,CPU 在退出中断后立即停止了呢?2,也就是说,进入LP 模式后, ...
- 【转】Android应用程序的数据存放目录解说
Android的每个应用程序,都有自己的可控的目录. 在Setting/Application info里面,可以看到每个应用程序,都有Clear data和Clear cache选项. 具体这些目录 ...
- Sharepoint 移动客户端 Rshare的特点
1.随时随地快速访问SharePoint,和同事高效合作,实时浏览日历信息,完整日程安排.查看联系人信息.浏览公告,文档和图片等. 添加图片到相册,通过Email和他人分享. 2.新建.上传:新建日历 ...
- 读jQuery官方文档:$(document).ready()与避免冲突
$(document).ready() 通常你想在DOM结构加载完毕之后才执行相关脚本.使用原生JavaScript,你可能调用window.onload = function() { ... }, ...
- AIX 配置vncserver
我们安装数据库时,很多情况下客户现场并没有配置图形界面,这是就需要自己配置.vnc就是一个很好的工具vnc rpm包(vnc-3.3.3r2-6.aix5.1.ppc.rpm)下载地址为http:// ...
- 不显示UITableView底部多余的分割线
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];