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列表推导式的使用方法
Nov 21 Python
python实现批量转换文件编码(批转换编码示例)
Jan 23 Python
Python实现选择排序
Jun 04 Python
Python实现获取前100组勾股数的方法示例
May 04 Python
python3实现逐字输出的方法
Jan 23 Python
在python中画正态分布图像的实例
Jul 08 Python
Python面向对象编程基础实例分析
Jan 17 Python
python3+selenium获取页面加载的所有静态资源文件链接操作
May 04 Python
Python tkinter实现简单加法计算器代码实例
May 13 Python
Python中Selenium模块的使用详解
Oct 09 Python
python中的None与NULL用法说明
May 25 Python
解决Python中的modf()函数取小数部分不准确问题
May 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下判断数组中是否存在相同的值array_unique
2008/03/25 PHP
让你成为更出色的PHP开发者的10个技巧
2011/02/25 PHP
php数组添加元素方法小结
2014/12/20 PHP
PHP实践教程之过滤、验证、转义与密码详解
2017/07/24 PHP
通过JAVASCRIPT读取ASP设定的COOKIE
2007/02/15 Javascript
JQuery加载图片自适应固定大小的DIV
2013/09/12 Javascript
jQuery实现动画效果的简单实例
2014/01/27 Javascript
javascript中的括号()用法小结
2014/04/14 Javascript
jquery判断input值不为空的方法
2016/06/05 Javascript
Bootstrap零基础入门教程(三)
2016/07/18 Javascript
URL中“#” “?” &“”号的作用浅析
2017/02/04 Javascript
MUI 上拉刷新/下拉加载功能实例代码
2017/04/13 Javascript
微信小程序中hidden不生效原因的解决办法
2017/04/26 Javascript
vue中使用echarts制作圆环图的实例代码
2018/07/27 Javascript
解决vue点击控制单个样式的问题
2018/09/05 Javascript
js计算两个日期间的天数月的实例代码
2018/09/20 Javascript
js实现unicode码字符串与utf8字节数据互转详解
2019/03/21 Javascript
在Express中提供静态文件的实现方法
2019/10/17 Javascript
[02:38]DOTA2 夜魇暗潮2020活动介绍官方视频
2020/11/04 DOTA
python 随机数生成的代码的详细分析
2011/05/15 Python
python消除序列的重复值并保持顺序不变的实例
2018/11/08 Python
wxPython实现文本框基础组件
2019/11/18 Python
解决Keras中CNN输入维度报错问题
2020/06/29 Python
详解HTML5 data-* 自定义属性
2018/01/24 HTML / CSS
Lookfantastic葡萄牙官方网站:欧洲第一大化妆品零售商
2018/03/17 全球购物
Stubhub英国:购买体育、演唱会和剧院门票
2018/06/10 全球购物
FLIR美国官网:热成像, 夜视和红外摄像系统
2018/07/13 全球购物
工作中的自我评价如何写好
2013/10/28 职场文书
关于打架的检讨书
2014/01/17 职场文书
高中生物教学反思
2014/02/05 职场文书
人力资源经理的岗位职责范本
2014/02/28 职场文书
团日活动总结怎么写
2014/06/25 职场文书
三提三创主题教育活动查摆整改措施
2014/10/25 职场文书
2014年生活老师工作总结
2014/12/23 职场文书
义诊活动总结
2015/02/04 职场文书
2015迎新晚会活动总结
2015/07/16 职场文书