最近用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 中模块间全局变量的使用上的注意的更多相关文章

  1. Python中模块之os的功能介绍

    Python中模块之os的功能介绍 1. os的变量 path 模块路径 方法:os.path 返回值:module 例如:print(os.path) >>> <module ...

  2. [python]关于在python中模块导入问题追加总结

    [背景] 最近在写程序时,我使用的eclipse编辑器运行都没有问题,然后部署到自动化环境上却偏偏报找不到相应模块问题,现在对该问题在之前的贴子上追加总结 原帖子:[python]关于python中模 ...

  3. 查看python中模块的所有方法

    查看python中模块的所有方法     安装的python模块,现将查看方法总结如下 一.CMD命令行下使用pydoc命令 在命令行下运行$ pydoc modules即可查看 二.在python交 ...

  4. [笔记]Python中模块互相调用的例子

    python中模块互相调用容易出错,经常是在本地路径下工作正常,切换到其他路径来调用,就各种模块找不到了. 解决方法是通过__file__定位当前文件的真实路径,再通过sys.path.append( ...

  5. python中进程间通讯——文件锁之fcntl模块的使用

    python 中给文件加锁——fcntl模块import fcntl 打开一个文件##当前目录下test文件要先存在,如果不存在会报错.或者以写的方式打开f = open('./test')对该文件加 ...

  6. Python中模块

    模块 模块对我来说是什么 模块对我来说,感觉就像亲属或者朋友已经走过的路,他们已经趟过的浑水.掉过的坑.践行过的路线,全部提供给你,在你需要的时候请求帮助,借鉴他们的解决方法一样.都是为了方便走好人生 ...

  7. python 中 模块,包, 与常用模块

    一 模块 模块:就是一组功能的集合体, 我们的程序可以直接导入模块来复用模块里的功能 导入方式 一般为 : import 模块名 在python中, 模块一般分为四个通用类别 1使用python编写. ...

  8. python中模块和包的概念

    1.模块 一个.py文件就是一个模块.这个文件的名字是:模块名.py.由此可见在python中,文件名和模块名的差别只是有没有后缀.有后缀是文件名,没有后缀是模块名. 每个文件(每个模块)都是一个独立 ...

  9. python中模块的制作

    1.import 模块名 2.from 模块名 import 类名(或方法名或全局变量) 3.from 模块名 import *   导入模块名下的所有类名,方法,全局变量 4.from 模块名 im ...

随机推荐

  1. Docker intercontainer 网络解释

    https://segmentfault.com/a/1190000000669312

  2. linux内核系统调用和标准C库函数的关系分析

    http://blog.csdn.net/skyflying2012/article/details/10044343

  3. JS获取活动区域高和宽

    var width;            var height;            //获取窗口宽度            if (window.innerWidth)              ...

  4. Flume连接Kafka的broker出错

    在启动Flume的时候,出现下面的异常,但是程序照样能运行,Kafka也能够收到数据,只是偶尔会断点. 2016-08-25 15:32:54,561 (SinkRunner-PollingRunne ...

  5. aggregation 详解3(bucket aggregation)

    概述 桶分聚合不进行权值的计算,他们对文档根据聚合请求中提供的判断条件(比如:{"from":0,  "to":100})来进行分组(桶分). 桶分聚合还会额外 ...

  6. Centos 7中 vim 中文乱码

    参考:http://www.myexception.cn/operating-system/1534005.html 一. sudo vim /etc/vimrc 在文件中加入如下几行:      s ...

  7. PHP 有关上传图片时返回HTTP 500错误

    1. 检查PHP GD 扩展库是否开启或者安装 在Ubuntu server中,在php -m 之后,未看到gd扩展,所以需要安装gd,然后重启apache2 sudo apt-get install ...

  8. (转)战斗bug技巧全攻略

    原文地址:http://www.cnblogs.com/manuosex/p/3736077.html 程序员不是有一幅这样的对联吗 上联:一个项目两部电脑三餐盒饭只为四千工资搞得五脏俱损六神无主仍然 ...

  9. FusionChart 导出图片 功能实现(转载)

    FusionChart 导出图片 功能实现(转载) http://www.cnblogs.com/jiagoushi/archive/2013/02/05/2893468.html 题目:精美Fusi ...

  10. 隐藏NavigationBar 带来的坑

    一.场景介绍 现在大多数APP 都有一个需求,就是隐藏某一个页面的NavigationBar.很多开发者直接   [self.navigationController setNavigationBar ...