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进行一些简单的自然语言处理的教程
Mar 31 Python
python enumerate函数的使用方法总结
Nov 15 Python
python中set()函数简介及实例解析
Jan 09 Python
利用python实现微信头像加红色数字功能
Mar 26 Python
Python实现常见的回文字符串算法
Nov 14 Python
对python中UDP,socket的使用详解
Aug 22 Python
python lambda表达式在sort函数中的使用详解
Aug 28 Python
关于Tensorflow分布式并行策略
Feb 03 Python
Python修改列表值问题解决方案
Mar 06 Python
Python3操作读写CSV文件使用包过程解析
Apr 10 Python
numpy库reshape用法详解
Apr 19 Python
基于Python和openCV实现图像的全景拼接详细步骤
Oct 05 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获取当前网址及域名的实现代码
2013/06/23 PHP
PHP设计模式之适配器模式代码实例
2015/05/11 PHP
php基于双向循环队列实现历史记录的前进后退等功能
2015/08/08 PHP
php 生成加密公钥加密私钥实例详解
2017/06/16 PHP
PHP简单获取上月、本月、近15天、近30天的方法示例
2017/07/03 PHP
PHP实现双链表删除与插入节点的方法示例
2017/11/11 PHP
javascript上传图片前预览图片兼容大多数浏览器
2013/10/25 Javascript
javascript异步编程的4种方法
2014/02/19 Javascript
jQuery实现复选框成对选择及对应取消的方法
2015/03/03 Javascript
【JS+CSS3】实现带预览图幻灯片效果的示例代码
2016/03/17 Javascript
限制只能输入数字的实现代码
2016/05/16 Javascript
jQuery插件autocomplete使用详解
2017/02/04 Javascript
看看“疫苗查询”小程序有温度的代码
2018/07/31 Javascript
node.js文件的复制、创建文件夹等相关操作
2021/02/05 Javascript
three.js 实现露珠滴落动画效果的示例代码
2021/03/01 Javascript
Python判断Abundant Number的方法
2015/06/15 Python
儿童学习python的一些小技巧
2018/05/27 Python
把csv文件转化为数组及数组的切片方法
2018/07/04 Python
PyQt5的安装配置过程,将ui文件转为py文件后显示窗口的实例
2019/06/19 Python
python3 pathlib库Path类方法总结
2019/12/26 Python
Python自动化测试笔试面试题精选
2020/03/12 Python
Melissa香港官网:MDreams
2016/07/01 全球购物
北欧最好的童装网上商店:Babyshop
2019/09/15 全球购物
linux系统都有哪些运行级别
2016/03/26 面试题
JSF的标签库有哪些
2012/04/27 面试题
董事长秘书职责
2014/01/31 职场文书
群众路线个人整改措施
2014/10/24 职场文书
部门经理迟到检讨书
2015/02/16 职场文书
父亲节寄语大全
2015/02/27 职场文书
2015年采购员工作总结
2015/04/27 职场文书
离婚案件上诉状
2015/05/23 职场文书
公司回复函格式
2015/07/14 职场文书
公司酒会致辞
2015/07/30 职场文书
导游带团欢迎词
2015/09/30 职场文书
Python爬虫基础初探selenium
2021/05/31 Python
使用qt quick-ListView仿微信好友列表和聊天列表的示例代码
2021/06/13 Python