Python全局变量在模块之间引用的问题
2013-10-10 11:42
579 查看
昨天在Python群里有人提到一个问题,在模块a中引入模块b的全局变量x,并在a中调用b的函数来修改x的值,结果出现很难理解的现象。经过反思发现自己对这个概念也是一知半解,好像在《Python源码剖析》那本书中看到过相关的知识但是又有些记不太清,故编写程序做一些验证以扫清编码障碍,至于实现层面的理解等晚一点再翻翻书(PS: 这件事情显示读书笔记还是很重要的,不然每次都得去书中重新找相关信息)。
这其实是两个问题:1.from moduleA import * 和import moduleA在使用全局变量上的区别; 2.__main__模块横插一脚会怎样?
1.程序
结果
一目了然,不做赘述!
2.程序
结果
把testa模块作为__main__模块时,在内存中__main__模块跟testa模块虽然是由相同的源码(相同的字节码文件testa.pyc)加载的,但是它们是两个独立的module对象
这其实是两个问题:1.from moduleA import * 和import moduleA在使用全局变量上的区别; 2.__main__模块横插一脚会怎样?
1.程序
[dongsong@localhost python_study]$ cat testc.py import pprint, sys, pdb a = list() b = list() def A(): global a a = dict() b.append(100) print "A() a = %r, b = %r" % (a,b) [dongsong@localhost python_study]$ cat testd.py #encoding=utf8 import pprint, sys, pdb if __name__ == "__main__": if len(sys.argv) == 1: print "Usage:\n\tpython %s 1/2" % __file__ sys.exit() if int(sys.argv[1]) == 1: print "import testc ..." import testc print "testc.a = %r, testc.b = %r" % (testc.a, testc.b) testc.A() print "testc.a = %r, testc.b = %r" % (testc.a, testc.b) elif int(sys.argv[1]) == 2: print "from testc import *" print "before import: globals().keys() = %r" % globals().keys() from testc import * print "after import: globals().keys() = %r" % globals().keys() #可以看到testc模块中的符号都被导入__main__模块的全局名字空间里了 print "a = %r, b = %r, sys.modules['testc'].a = %r, sys.modules['testc'].b = %r" % (a, b, sys.modules['testc'].a, sys.modules['testc'].b) A() #WARNING:A()函数让testc模块中的符号a指向了新的对象,故testc和__main__中的"a"符号指向了不同对象;A()函数没有改变"b"符号指向的对象,只是修改了该对象的元素,故testc和__main__中的"b"符号对应的数值都跟着变化(还是指向同一个对象) print "a = %r, b = %r, sys.modules['testc'].a = %r, sys.modules['testc'].b = %r" % (a, b, sys.modules['testc'].a, sys.modules['testc'].b) else: print "error argv.."
结果
[dongsong@localhost python_study]$ vpython testd.py 1 import testc ... testc.a = [], testc.b = [] A() a = {}, b = [100] testc.a = {}, testc.b = [100] [dongsong@localhost python_study]$ vpython testd.py 2 from testc import * before import: globals().keys() = ['__builtins__', '__file__', 'pprint', '__package__', 'sys', 'pdb', '__name__', '__doc__'] after import: globals().keys() = ['a', 'A', 'b', '__builtins__', '__file__', 'pprint', '__package__', 'sys', 'pdb', '__name__', '__doc__'] a = [], b = [], sys.modules['testc'].a = [], sys.modules['testc'].b = [] A() a = {}, b = [100] a = [], b = [100], sys.modules['testc'].a = {}, sys.modules['testc'].b = [100]
一目了然,不做赘述!
2.程序
[dongsong@localhost python_study]$ cat testa.py import pprint, sys, pdb a = list() b = list() def A(): global a a = dict() b.append(100) print "A() a = %r, b = %r" % (a,b) if __name__ == '__main__': import testa testaInModules = sys.modules['testa'] testaAsMain = sys.modules['__main__'] print "testa: id = %r, file = %r" % (id(testa), testa.__file__) print "testaInModules: id = %r, file = %r" % (id(testaInModules), testaInModules.__file__) print "testaAsMain: id = %r, file = %r" % (id(testaAsMain), testaAsMain.__file__) print "" A() print "" print "testa: a = %r, b = %r" % (testa.a,testa.b) print "testaInModules: a = %r, b = %r" % (testaInModules.a,testaInModules.b) print "testaAsMain: a = %r, b = %r" % (testaAsMain.a,testaAsMain.b) print "" #import testb #testb.B()
结果
[dongsong@localhost python_study]$ vpython testa.py testa: id = 140681127912120, file = '/home/dongsong/python_study/testa.py' testaInModules: id = 140681127912120, file = '/home/dongsong/python_study/testa.py' testaAsMain: id = 140681230481008, file = 'testa.py' A() a = {}, b = [100] testa: a = [], b = [] testaInModules: a = [], b = [] testaAsMain: a = {}, b = [100]
把testa模块作为__main__模块时,在内存中__main__模块跟testa模块虽然是由相同的源码(相同的字节码文件testa.pyc)加载的,但是它们是两个独立的module对象
相关文章推荐
- Python中模块之间变量引用的方法说明
- Python多模块全局变量引用和修改
- VS2008编译环境下全局const变量在其他编译模块中引用注意的问题
- Python中模块之间变量引用的方法说明
- Python中模块之间变量引用的方法说明
- Python 专题六 局部变量、全局变量global、导入模块变量
- python对象、引用、全局变量和局部变量的关系
- python 模块被引用多次但是里面的全局表达式总共只会执行一次
- PHP中关于在函数内引用全局变量的问题
- Python 进程之间共享数据(全局变量)
- 关于Python函数定义全局变量执行弹出SyntaxWarning的问题
- 主程序与DLL之间的全局变量问题
- 主程序与DLL之间的全局变量问题
- python3 动态模块导入与全局变量使用
- 在python中实现生产者和消费者的例子(五):使用threading模块和全局变量
- (原)python中不同文件之间使用所谓的全局变量
- PHP中关于在函数内引用全局变量的问题
- Block引用全局变量处理(内存泄露问题)
- 零基础学python-16.5 模块间全局变量的修改以及其他访问全局变量的方法
- python 变量赋值,引用,初始化问题