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脚本操作MongoDB的教程
Apr 16 Python
对pandas中apply函数的用法详解
Apr 10 Python
PyQt4实现下拉菜单可供选择并打印出来
Apr 20 Python
查看django版本的方法分享
May 14 Python
Python定时任务sched模块用法示例
Jul 16 Python
Python3 实现串口两进程同时读写
Jun 12 Python
对Django 中request.get和request.post的区别详解
Aug 12 Python
Python对列表的操作知识点详解
Aug 20 Python
python中的线程threading.Thread()使用详解
Dec 17 Python
python实现飞行棋游戏
Feb 05 Python
15个应该掌握的Jupyter Notebook使用技巧(小结)
Sep 23 Python
Python3中FuzzyWuzzy库实例用法
Nov 18 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
模拟OICQ的实现思路和核心程序(一)
2006/10/09 PHP
php实现的树形结构数据存取类实例
2014/11/29 PHP
PHP数学运算与数据处理实例分析
2016/04/01 PHP
php下的原生ajax请求用法实例分析
2020/02/28 PHP
YII2框架中使用RBAC对模块,控制器,方法的权限控制及规则的使用示例
2020/03/18 PHP
PHP mkdir创建文件夹实现方法解析
2020/11/13 PHP
Firebug 字幕文件JSON地址获取代码
2009/10/28 Javascript
关于火狐(firefox)及ie下event获取的两种方法
2012/12/27 Javascript
JQuery弹出层示例可自定义
2014/05/19 Javascript
javascript在网页中实现读取剪贴板粘贴截图功能
2014/06/07 Javascript
javascript随机之洗牌算法深入分析
2014/06/07 Javascript
JavaScript实现在标题栏上显示当前日期的方法
2015/03/19 Javascript
JS 面向对象之继承---多种组合继承详解
2016/07/10 Javascript
基于JavaScript实现购物网站商品放大镜效果
2016/09/06 Javascript
深入理解bootstrap框架之第二章整体架构
2016/10/09 Javascript
javascript iframe跨域详解
2016/10/26 Javascript
jquery.masonry瀑布流效果
2017/05/25 jQuery
JQuery实现table中tr上移下移的示例(超简单)
2018/01/08 jQuery
JavaScript中的全局属性与方法深入解析
2020/06/14 Javascript
vue 页面回退mounted函数不执行的解决方案
2020/07/26 Javascript
Python类的专用方法实例分析
2015/01/09 Python
Python编程之字符串模板(Template)用法实例分析
2017/07/22 Python
Pandas统计重复的列里面的值方法
2019/01/30 Python
在PyTorch中Tensor的查找和筛选例子
2019/08/18 Python
Python socket模块ftp传输文件过程解析
2019/11/05 Python
python 导入数据及作图的实现
2019/12/03 Python
使用Jupyter notebooks上传文件夹或大量数据到服务器
2020/04/14 Python
HTML5实践-图片设置成灰度图
2012/11/12 HTML / CSS
P D PAOLA意大利官网:西班牙著名的珠宝首饰品牌
2019/09/24 全球购物
软件测试工程师笔试题带答案
2015/03/27 面试题
公司部门司机岗位职责
2014/01/03 职场文书
教师个人自我评价范文
2014/04/13 职场文书
管理建议书范文
2014/05/13 职场文书
幼儿学前班评语
2014/12/29 职场文书
2016年感恩节寄语
2015/12/07 职场文书
Android开发手册Chip监听及ChipGroup监听
2022/06/10 Java/Android