最近用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. careercup-中等难度 17.3

    17.3 写一个算法计算n的阶乘末尾0的个数? 解答: 首先,算出n的阶乘的结果再去计算末尾有多少个0这种方法是不可取的, 因为n的阶乘是一个非常大的数,分分种就会溢出.我们应当去分析, 是什么使n的 ...

  2. 初学Node.js第一天

    最近开始下班到家不知道该做啥,因为水平太菜,要学的东西实在太多,反而陷入了不知道该学什么的困境,结果天天就是看别人的博客,看到什么标题比较感兴趣就点进去,没有一个目标. 今天突然兴起,决定要捣鼓捣鼓N ...

  3. Windows 8.1 Hyper-V安装的虚拟机

    一.安装Hyper-v Hyper-V内置于Windows 8中,用户无需格外的下载安装文件,只需要到Windows 8的程序管理中将其选中开启功能即可. 具体步骤:控制面板→程序→启用或关闭Wind ...

  4. php实用函数整理

    1. 排序:array_multisort 可以对多位数组的多个字段进行排序 例子1如下: //自定义数组排序--按转发数从高到低排序 function sortSelfRc($oneLayer){ ...

  5. 在aws ec2上使用root用户登录

    aws ec2默认是使用ec2-user账号登陆的,对很多文件夹是没有权限的.如何使用root账号执行命令就是一个问题了.解决办法如下: 1.根据官网提供的方法登录连接到EC2服务器(官网推荐wind ...

  6. Spring3之事务管理

    事务管理是企业应用开发中确保数据完整性和一致性的关键技术.对于并发和分布式坏境中从不可预期的错误中恢复来说,事务管理特别重要.Spring作为一个企业应用框架,在不同的事务管理API之上提供了一个抽象 ...

  7. Android四大组件之服务-Service 原理和应用开发详解

    一.Android 服务简介 Service是android 系统中的四大组件之一(Activity.Service.BroadcastReceiver.ContentProvider),它跟Acti ...

  8. 绿荫工作室爱选修app内测

    下载地址:http://greendasungta.com/greencms/ixuanxiu.apk 开发目的是用于方便在校生的选课操作以及对选修课的交流.

  9. javascript的函数传参(没有引用传递只有值传递)

    var v1 = [] var v2 = {}; var v3 = {}; function foo(v1, v2, v3){    v1 = [1];    v2 = [2];    v3 = {a ...

  10. Android开发了解——AAPT

    aapt即Android Asset Packaging Tool , 在SDK的build-tools目录下. 该工具可以查看, 创建, 更新ZIP格式的文档附件(zip, jar, apk). 也 ...