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:           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。

显然,这个算不上是「全局变量」了。

时间: 2024-10-11 19:44:29

Python 中模块间全局变量的使用上的注意的相关文章

零基础学python-16.5 模块间全局变量的修改以及其他访问全局变量的方法

这一章节我们来讨论一下python里面模块间全局变量的修改以及其他访问全局变量的方法 1.模块间全局变量的修改 x=1#全局变量,其实就是模块里面所有的函数都可以使用 def test(): print(x) if __name__=='__main__': test() 上面的代码保存为test.py import test if __name__=='__main__': test.x=2 test.test() print(test.x) 上面的代码保存为test2.py 我们运行test

查看python中模块的所有方法

查看python中模块的所有方法 安装的python模块,现将查看方法总结如下 一.CMD命令行下使用pydoc命令 在命令行下运行$ pydoc modules即可查看 二.在python交互解释器中使用help()查看 在交互式解释器中输入>>> help("modules")即可,效果跟在命令行下输入$ pydoc modules是一样的 三.在python交互的解释器下导入sys模块查看 # python的sys模块也是可以用来查看模块信息的     >

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

一 模块 模块:就是一组功能的集合体, 我们的程序可以直接导入模块来复用模块里的功能 导入方式 一般为 : import 模块名 在python中, 模块一般分为四个通用类别 1使用python编写.py 文件 2.已被编译为共享库或DLL 的c 或c++扩展 3把一系列模块组织到一起的文件夹(注:文件夹下有一个__init__.py文件,该文件夹称之为包) 4.使用c编写并链接到python解释器的内置模块 使用模块的优点: 1.从文件级别组织程序, 更方便管理 2.拿来主义, 提升开发效率

python中模块和包的概念

1.模块 一个.py文件就是一个模块.这个文件的名字是:模块名.py.由此可见在python中,文件名和模块名的差别只是有没有后缀.有后缀是文件名,没有后缀是模块名. 每个文件(每个模块)都是一个独立的名称空间,也就是说可以在两个(多个)文件中出现同名的函数. import,from.....import...两种导入的区别: 1.import 按模块区分拥有独立的命名空间,要是想使用模块中的函数需要使用      模块名.函数名       的方式来使用. 可以使用import.....as.

Python中模块(Module)和包(Package)的区别

1. 模块(Module) 在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式.在Python中,一个.py文件就称之为一个模块(Module). 使用模块有什么好处? 最大的好处是大大提高了代码的可维护性.其次,编写代码不必从零开始.当一个模块编写完毕,就可以被其他地方引用.我们在编写程序的时候,也经常引用其他模

Python中模块的发布与安装

模块(Module) Python中有一个概念叫做模块(module),这个和C语言中的头文件以及Java中的包很类似,比如在Python中要调用sqrt函数,必须用import关键字引入math这个模块.通俗的来说,模块就好比是工具包,要想使用这个工具包中的工具(就好比函数),就需要导入这个模块. 导入模块 import: 引入具体模块,可以一次性引入多个模块,使用逗号隔开即可 eg:import modlue1,module2,module3,.....moduleN ,   使用模块中的函

关于python中模块的import路径

前两天被一个同事问了一个python的问题: 为什么一个目录里的python文件引用不要另一个兄弟目录的python文件,但是这两个目录的父母录运行时是可以引用到了.当时感觉一直是模块和包的机制问题,回来翻了一下书,发现是引用路径的问题,记录一下. 在python中我们import模块时,系统会在python的引用路径下去查找这个模块文件, 这个引用路径是在编译或者安装的时候指定的,可以在两个地方进行修改: shell的PYTHONPATH环境变量,系统会在这个变量的目录中进行查找. 在pyth

Python中模块使用及面向对象介绍

1.模块使用 模块: 模块式pyth1.on组织代码的基本方式 一个python脚本可以单独运行,也可以导入另一个脚本中运行,当脚本被导入运行时,我们将其称为模块(module) 所有的点p为文件都可以作为一个模块导入 模块名与脚本的文件名相同,例如我们编写了一个名为hello.pv的脚本则可以在另一个脚本中用import hello.py来导入它 包: python的模块可以按目录组织为包 创建一个包的步骤: 创建一个名字为包名字的目录,在该目录下创建一个__init__.py文件,根据需要在

Python学习笔记:Python中模块的引入

在Python开发(http://www.maiziedu.com/course/python-px/)中用关键字import来引入某个模块,也就类似于C++中include某个头文件.比如要引用模块math,就可以在文件最开始的地方用import math来引入.在调用math模块中的函数时,必须这样引用,详情见代码: >>>improt math >>>math.sin(0) 导入自己的模块: #hello.pyprint "Hello world!&qu