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 ...
随机推荐
- C 高级编程4 makefile 与 IO
make 与 makefile .目标的语法 目标名:依赖目标 @命令 @命令 make的命令行使用 make -f make 脚本文件 目标名 .目标的划分 demo.mk demo: gcc -c ...
- python内存管理
python对象三要素: identity(值):对应于内存的地址,不可修改 type(类型):不可修改 value(值): mutable :可以修改 immutable:不可以修改 引用计数 当引 ...
- visual studio 2013 有效序列号
还没试过,可以参考下! visual studio 2013 有效序列号: BWG7X-J98B3-W34RT-33B3R-JVYW9
- myeclipse连接数据库遇到的几个问题
1:无效的SQL URL: //将获取的参数插入数据库 Connection conn=null; PreparedStatement stat=null; ...
- mysql命令行方式添加用户及设置权限
以前总是喜欢通过phpmyadmin去添加用户和数据库,这次装完系统后,配置了一大堆东东,实在不想安装phpmyadmin了,就通过命令行方式创建了数据库和设置权限,记录一下,免得以后总是百度 关键步 ...
- [关于SQL]查询成绩都大于80分的学生
1.用一条SQL语句 查询出每门课都大于80分的学生姓名name kecheng fenshu张三 语文 81张三 数学 75李四 语文 76李四 数学 90王五 语文 81王五 数学 100王五 英 ...
- [原]unity中WWW isDone方法只能在主线程中调用
项目中要使用动态加载,原计划是生成WWW对象后,放到一个容器里.由一个独立线程轮询容器里的对象,如果www.isDone为true时,回调一个接口把结果交给请求方. new Thread( new T ...
- 电脑小白学习软件开发-C#语言基础之循环重点讲解,习题
写代码也要读书,爱全栈,更爱生活.每日更新原创IT编程技术及日常实用视频. 我们的目标是:玩得转服务器Web开发,搞得懂移动端,电脑客户端更是不在话下. 本教程是基础教程,适合任何有志于学习软件开发的 ...
- 【转】必需知道的 SharePoint 权限 Tips
SharePoint Tips about Permissions: What you need to know I have been writing tips about Shar ...
- 默认安装wamp修改MySQL密码
首先,通过WAMP打开mysql控制台. 提示输入密码,因为现在是空,所以直接按回车. 然后输入“use mysql”,意思是使用mysql这个数据库,提示“Database changed”就行. ...