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中cPickle用法例子分享
Jan 03 Python
用Python实现QQ游戏大家来找茬辅助工具
Sep 14 Python
利用Python绘制数据的瀑布图的教程
Apr 07 Python
django+js+ajax实现刷新页面的方法
May 22 Python
Python使用flask框架操作sqlite3的两种方式
Jan 31 Python
Python2 Selenium元素定位的实现(8种)
Feb 25 Python
Python制作词云图代码实例
Sep 09 Python
理解python中装饰器的作用
Jul 21 Python
进行数据处理的6个 Python 代码块分享
Apr 06 Python
python pygame 开发五子棋双人对弈
May 02 Python
Python使用openpyxl模块处理Excel文件
Jun 05 Python
virtualenv隔离Python环境的问题解析
Jun 21 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 柱状图实现代码
2009/12/04 PHP
深入解析php之apc
2013/05/15 PHP
php利用scws实现mysql全文搜索功能的方法
2014/12/25 PHP
JQuery打造省市下拉框联动效果
2014/05/18 Javascript
jQuery+css实现百度百科的页面导航效果
2014/12/16 Javascript
JS获得图片alt信息的方法
2015/04/01 Javascript
jQuery实现购物车表单自动结算效果实例
2015/08/10 Javascript
Node.js中使用jQuery的做法
2016/08/17 Javascript
Vue监听数据对象变化源码
2017/03/09 Javascript
nodejs学习笔记之路由
2017/03/27 NodeJs
JavaScript实现省市县三级级联特效
2017/05/16 Javascript
Angularjs 事件指令详细整理
2017/07/27 Javascript
JS中的Replace()传入函数时的用法详解
2017/09/11 Javascript
Vue中自定义全局组件的实现方法
2017/12/08 Javascript
图文详解vue框架安装步骤
2019/02/12 Javascript
小程序封装wx.request请求并创建接口管理文件的实现
2019/04/29 Javascript
JS数组的常用10种方法详解
2020/05/08 Javascript
Element-ui el-tree新增和删除节点后如何刷新tree的实例
2020/08/31 Javascript
对python中xlsx,csv以及json文件的相互转化方法详解
2018/12/25 Python
Django REST framework视图的用法
2019/01/16 Python
python字符串反转的四种方法详解
2019/12/02 Python
python3实现网页版raspberry pi(树莓派)小车控制
2020/02/12 Python
基于Keras 循环训练模型跑数据时内存泄漏的解决方式
2020/06/11 Python
如何在vscode中安装python库的方法步骤
2021/01/06 Python
css3中用animation的steps属性制作帧动画
2019/04/25 HTML / CSS
俄罗斯旅游网站:Tripadvisor俄罗斯
2017/03/21 全球购物
美国单身专业人士在线约会网站:EliteSingles
2019/03/19 全球购物
泰国第一在线超市:Tops
2021/02/13 全球购物
财务工作者先进事迹材料
2014/01/17 职场文书
敬老院标语
2014/06/27 职场文书
应用心理学专业求职信
2014/08/04 职场文书
停车位租赁协议书
2014/09/24 职场文书
教师批评与自我批评范文
2014/10/15 职场文书
大学军训通讯稿(2016最新版)
2015/12/21 职场文书
安全学习心得体会范文
2016/01/18 职场文书
go类型转换及与C的类型转换方式
2021/05/05 Golang