Python 中模块间全局变量的使用上的注意
2014-09-21 21:40
726 查看
最近用Python写代码,需要用到模块间的全局变量。
网上四处搜索,发现普遍做法是把全局变量放到一个独立的模块中,使用时,导入此全局变量模块即可。
但是在实际使用过程中发现了些小问题:在使用如下代码导入全局变量模块时,各个模块获取到的全局变量都是初始值。
但是如果使用「模块名.全局变量名」来访问时,却又是正常的:
为了弄清其中的原委,我写了个测试程序来仔细查看其中的细节:
m1.py
m2.py
运行结果:
在这种方式下,如果是改变对象本身的操作(append),各个模块内部的操作都是针对于同一个对象。
而赋值操作,虽然全局变量所指向的对象改变了,但是全局变量本身依然在各个模块内部能够正确访问,这正是我所希望的效果。
m1.py
m2.py
运行结果:
这次,运行结果和上次略有不同。
改变对象本身的操作(append)和之前的例子一样,全局变量始终指向相同的对象。
但是赋值操作就比较奇怪了。注意标红部分,每个模块第一次获取到的这个「全局变量」都是相同id的对象。即使这个「全局变量」在其他模块中已经被重新赋值,但在本模块中依然指向的是最原始的id。
显然,这个算不上是「全局变量」了。
网上四处搜索,发现普遍做法是把全局变量放到一个独立的模块中,使用时,导入此全局变量模块即可。
但是在实际使用过程中发现了些小问题:在使用如下代码导入全局变量模块时,各个模块获取到的全局变量都是初始值。
from module import global_var
但是如果使用「模块名.全局变量名」来访问时,却又是正常的:
import module print module.global_var
为了弄清其中的原委,我写了个测试程序来仔细查看其中的细节:
1. import module
global_var.pyGLOBAL_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.pyGLOBAL_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: 4539998360 [1, 2, 3, 'm1', 'm2'] m1: after assigning: 4540135112 ['m1'] m1: before calling m2.assign(): 4540135112 ['m1'] m2: before assiging: 4539998360 [1, 2, 3, 'm1', 'm2'] m2: after assiging: 4540135040 ['m2'] m1: after calling m2.assign(): 4540135112 ['m1']
这次,运行结果和上次略有不同。
改变对象本身的操作(append)和之前的例子一样,全局变量始终指向相同的对象。
但是赋值操作就比较奇怪了。注意标红部分,每个模块第一次获取到的这个「全局变量」都是相同id的对象。即使这个「全局变量」在其他模块中已经被重新赋值,但在本模块中依然指向的是最原始的id。
显然,这个算不上是「全局变量」了。
相关文章推荐
- Python 3 实现定义跨模块的全局变量和使用
- 在python中实现生产者和消费者的例子(四):使用thread模块和全局变量
- 10 Python 函数内使用全局变量注意项
- Python 3 实现定义跨模块的全局变量和使用
- python全局变量使用注意事项_
- 在python中实现生产者和消费者的例子(五):使用threading模块和全局变量
- python3 - 声明全局变量并在不同模块中的使用.
- 5.1 Python 函数-默认参数,*args,**kwargs的使用;作用域-局部空间使用全局变量需要注意的事项等
- python3 动态模块导入与全局变量使用
- python 在函数中使用全局变量的注意事项
- python 在函数中使用全局变量的注意事项
- Python全局变量在模块之间引用的问题
- 线程间无需特别的手段进行通信,因为线程间可以共享数据结构,也就是一个全局变量可以被两个线程同时使用,不过要注意的是线程间需要做好同步。
- python 学习记录(5)-变量、模块名的命名规则及random模块使用
- Python 中全局变量的使用说明
- python中全局变量的使用
- python 经验: from x import * 影响全局变量使用
- j2ee高并发时使用全局变量需要注意的问题
- python中全局变量的使用
- python 全局变量多个模块访问