python中from module import * 的一个坑
2014-07-20 00:00
786 查看
但还有另外一个问题 - 你以为你修改了某个变量,其实,被from module import *后的那个并没有被更新,非常危险,因为程序有可能还可以正常运行, 只不过结果错了,到了production才被发现就比较惨了。
举个例子:
你定义了一些变量在base模块中:
然后在一个模块中用from module import 的方式读它:
在另外一个模块中写它:
然后先写,后读,看写的内容是否有效:
结论是没有,原因是:
当你用from module import时,其实是copy了一份reference或者pointer,指向一份内存,var和module.var都指向同一份内存
当你修改module.var时,其实你是让它指向了另外一份内存,此时var和module.var指向的是不同的内存
所以,虽然module.var的值变了,var还是指向原来那份内存,原来的值
这个对于object,比较容易理解,你可以直接修改object里的值,这个是有效的,但是当你指向另外一个object时就无效了。 对于primitive类型来讲,其实也是一个道理,因为每次赋值,都是让其指向一个不同的内存地址,而不是inplace修改已有的那份内存 - 这个很容易验证:
所以,建议是除非是一个quick and dirty的脚本,否则不要使用from module import *!
例子: https://github.com/baiyanhuang/blog/tree/master/arena/python/from_module_import
举个例子:
你定义了一些变量在base模块中:
# reference data type class Demo: def __init__(self, name): self.name = name demo = Demo('Demo') # primitive type foo = 1
然后在一个模块中用from module import 的方式读它:
from base import * def read(): print 'reference data id: ' + str(id(demo)) print 'reference data value : ' + demo.name print 'primitive data id: ' + str(id(foo)) print 'primitive data value: ' + str(foo)
在另外一个模块中写它:
import base def write(): print "\nOriginal:" print "Original reference data id: " + str(id(base.demo)) base.demo.name = "Updated Demo" # this will reflect that change #base.demo = base.Demo("Updated Demo") # this won't relfect the change print "Original data id: " + str(id(base.foo)) base.foo = 1000 print "Original data id after assignment: " + str(id(base.foo))
然后先写,后读,看写的内容是否有效:
import read import write print "before write" read.read() write.write() print "\nafter write" read.read()
结论是没有,原因是:
当你用from module import时,其实是copy了一份reference或者pointer,指向一份内存,var和module.var都指向同一份内存
当你修改module.var时,其实你是让它指向了另外一份内存,此时var和module.var指向的是不同的内存
所以,虽然module.var的值变了,var还是指向原来那份内存,原来的值
这个对于object,比较容易理解,你可以直接修改object里的值,这个是有效的,但是当你指向另外一个object时就无效了。 对于primitive类型来讲,其实也是一个道理,因为每次赋值,都是让其指向一个不同的内存地址,而不是inplace修改已有的那份内存 - 这个很容易验证:
In [1]: a = 10 In [2]: id(a) Out[2]: 20429204 In [3]: a = 100 In [4]: id(a) Out[4]: 20430108
所以,建议是除非是一个quick and dirty的脚本,否则不要使用from module import *!
例子: https://github.com/baiyanhuang/blog/tree/master/arena/python/from_module_import
相关文章推荐
- Win32汇编教程四 编写一个简单的窗口
- 一个applicationContext 加载错误导致的阻塞解决小结
- 05-25日<一个简单实用的 vb 加密/解密算法>之改进
- 一个比较好的全排列算法(C语言)
- 写一个DX8的屏幕保护程序-------Alpha 闪烁效果
- Java.NET --一个基于Java的Microsoft.NET框架的实现
- 一个简单的tcp filter的例子
- ASP编写完整的一个IP所在地搜索类
- 非阻塞方式下Socket读取数据的一个例子
- 一个关于#include的问题
- 一个程序员在IBM的开发经验
- 在vb中如何区分一个变量值为中文还是英文字母?
- Visual C++6.0一个小BUG的解决方法
- 一个俄罗斯方块的源代码
- 一个统一的链表结构
- 源码推荐:一个使用C#绘制图形引擎的Framework
- [导入]查看mfc源码的一个很好的导航工具
- Win32汇编教程三 一个简单的对话框 --- 兼谈资源文件的使用
- 一个小程序轻松换回一辆宝马
- 一个黑客案列