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发腾讯微博代码分享
Jan 10 Python
Python map和reduce函数用法示例
Feb 26 Python
python按照多个字符对字符串进行分割的方法
Mar 17 Python
python获取本机mac地址和ip地址的方法
Apr 29 Python
python中常用的九种预处理方法分享
Sep 11 Python
Python模块结构与布局操作方法实例分析
Jul 24 Python
numpy实现合并多维矩阵、list的扩展方法
May 08 Python
利用python画出折线图
Jul 26 Python
Python3爬虫学习之将爬取的信息保存到本地的方法详解
Dec 12 Python
python实现控制电脑鼠标和键盘,登录QQ的方法示例
Jul 06 Python
Python JSON常用编解码方法代码实例
Sep 05 Python
python数字图像处理之对比度与亮度调整示例
Jun 28 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显示今天、今月、上月、今年的起点/终点时间戳的代码
2011/05/25 PHP
destoon实现调用当前栏目分类及子分类和三级分类的方法
2014/08/21 PHP
ThinkPHP打水印及设置水印位置的方法
2016/10/14 PHP
Zend Framework入门教程之Zend_Mail用法示例
2016/12/08 PHP
node.js中实现同步操作的3种实现方法
2014/12/05 Javascript
JavaScript数据库TaffyDB用法实例分析
2015/07/27 Javascript
微信小程序上传图片到服务器实例代码
2017/11/07 Javascript
vue底部加载更多的实例代码
2018/06/29 Javascript
atom-design(Vue.js移动端组件库)手势组件使用教程
2019/05/16 Javascript
详细教你微信公众号正文页SVG交互开发技巧
2019/07/25 Javascript
JS三级联动代码格式实例详解
2019/12/30 Javascript
js实现鼠标拖曳效果
2020/12/30 Javascript
linux下安装easy_install的方法
2013/02/10 Python
Python使用Windows API创建窗口示例【基于win32gui模块】
2018/05/09 Python
Python并行分布式框架Celery详解
2018/10/15 Python
Python操作MySQL数据库的两种方式实例分析【pymysql和pandas】
2019/03/18 Python
基于python实现FTP文件上传与下载操作(ftp&sftp协议)
2020/04/01 Python
python连接mysql数据库并读取数据的实现
2020/09/25 Python
Html5上传图片 移动端、PC端通用代码
2016/06/08 HTML / CSS
美国在线纱线商店:Darn Good Yarn
2019/03/20 全球购物
Moss Bros官网:英国排名第一的西装店
2020/02/26 全球购物
武汉世纪畅想数字传播有限公司 .NET笔试题
2015/06/13 面试题
计算机求职信
2013/12/01 职场文书
中级会计职业生涯规划范文
2014/01/16 职场文书
双十佳事迹材料
2014/01/29 职场文书
人力资源经理的岗位职责范本
2014/02/28 职场文书
端午节活动总结
2014/08/26 职场文书
质监局领导班子践行群众路线整改方案
2014/10/26 职场文书
迟到检讨书范文
2015/01/27 职场文书
2015年财政所工作总结
2015/04/25 职场文书
生死抉择观后感
2015/06/09 职场文书
师范生见习自我总结
2015/06/23 职场文书
《花钟》教学反思
2016/02/17 职场文书
2019年浪漫婚礼证婚词
2019/06/27 职场文书
redis调用二维码时的不断刷新排查分析
2022/04/01 Redis
python可视化分析绘制带趋势线的散点图和边缘直方图
2022/06/25 Python