python中from module import * 的一个坑


Posted in Python onJuly 20, 2014

但还有另外一个问题 - 你以为你修改了某个变量,其实,被from module import *后的那个并没有被更新,非常危险,因为程序有可能还可以正常运行, 只不过结果错了,到了production才被发现就比较惨了。

举个例子:

你定义了一些变量在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

Python 相关文章推荐
python使用urllib模块和pyquery实现阿里巴巴排名查询
Jan 16 Python
在Django中同时使用多个配置文件的方法
Jul 22 Python
Python 实现简单的电话本功能
Aug 09 Python
探究python中open函数的使用
Mar 01 Python
Python3 replace()函数使用方法
Mar 19 Python
PyQt5每天必学之日历控件QCalendarWidget
Apr 19 Python
解决Django的request.POST获取不到内容的问题
May 28 Python
对json字符串与python字符串的不同之处详解
Dec 19 Python
python实现播放音频和录音功能示例代码
Dec 30 Python
django admin后管定制-显示字段的实例
Mar 11 Python
解决python3.6用cx_Oracle库连接Oracle的问题
Dec 07 Python
Python中rapidjson参数校验实现
Jul 25 Python
用python代码做configure文件
Jul 20 #Python
python中的内置函数getattr()介绍及示例
Jul 20 #Python
Python实现的生成自我描述脚本分享(很有意思的程序)
Jul 18 #Python
Python中使用 Selenium 实现网页截图实例
Jul 18 #Python
Python中使用PyHook监听鼠标和键盘事件实例
Jul 18 #Python
python中使用pyhook实现键盘监控的例子
Jul 18 #Python
python使用pyhook监控键盘并实现切换歌曲的功能
Jul 18 #Python
You might like
php 搜索框提示(自动完成)实例代码
2012/02/05 PHP
php mysql_real_escape_string函数用法与实例教程
2013/09/30 PHP
解决php表单重复提交实现方法
2015/09/29 PHP
phpcms的分类名称和类别名称的调用
2017/01/05 PHP
将jQuery应用于login页面的问题及解决
2009/10/17 Javascript
javascript的数据类型、字面量、变量介绍
2012/05/23 Javascript
基于JQuery的列表拖动排序实现代码
2013/10/01 Javascript
jQuery jcrop插件截图使用方法
2013/11/20 Javascript
使用js显示当前时间示例
2014/03/02 Javascript
jquery显示隐藏input对象
2014/07/21 Javascript
javascript中关于&& 和 || 表达式的小技巧分享
2015/04/10 Javascript
基于JavaScript实现表单密码的隐藏和显示出来
2016/03/02 Javascript
Bootstrap Paginator分页插件使用方法详解
2016/05/30 Javascript
AngularJS中controller控制器继承的使用方法
2017/11/03 Javascript
Vue全局分页组件的实现代码
2018/08/10 Javascript
在vue中封装方法以及多处引用该方法详解
2020/08/14 Javascript
JavaScript实现雪花飘落效果
2020/12/27 Javascript
[55:45]DOTA2上海特级锦标赛D组败者赛 Liquid VS COL第一局
2016/02/28 DOTA
Python实现扫描局域网活动ip(扫描在线电脑)
2015/04/28 Python
python 判断字符串中是否含有汉字或非汉字的实例
2019/07/15 Python
django执行数据库查询之后实现返回的结果集转json
2020/03/31 Python
numpy库ndarray多维数组的维度变换方法(reshape、resize、swapaxes、flatten)
2020/04/28 Python
基于Python的图像阈值化分割(迭代法)
2020/11/20 Python
完美解决torch.cuda.is_available()一直返回False的玄学方法
2021/02/06 Python
css3图片边框border-image的用法
2017/06/30 HTML / CSS
详解CSS3选择器:nth-child和:nth-of-type之间的差异
2017/09/18 HTML / CSS
武汉瑞得软件笔试题
2015/10/27 面试题
高分子材料与工程专业个人求职信
2013/12/15 职场文书
表彰大会主持词
2014/03/26 职场文书
文体活动实施方案
2014/03/27 职场文书
企业安全生产目标责任书
2014/07/23 职场文书
我是一名护士演讲稿
2014/08/28 职场文书
2015年中秋节活动总结
2015/03/23 职场文书
2015年度学校卫生工作总结
2015/05/12 职场文书
因工资原因离职的辞职信范文
2015/05/12 职场文书
MySQL 逻辑备份与恢复测试的相关总结
2021/05/14 MySQL