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抽取指定url页面的title方法
May 11 Python
python验证码识别教程之利用投影法、连通域法分割图片
Jun 04 Python
python去除拼音声调字母,替换为字母的方法
Nov 28 Python
详解python中docx库的安装过程
Nov 08 Python
Python算法中的时间复杂度问题
Nov 19 Python
在Pytorch中计算卷积方法的区别详解(conv2d的区别)
Jan 03 Python
python机器学习库xgboost的使用
Jan 20 Python
Python如何把Spark数据写入ElasticSearch
Apr 18 Python
详解tensorflow2.x版本无法调用gpu的一种解决方法
May 25 Python
基于K.image_data_format() == 'channels_first' 的理解
Jun 29 Python
python读取excel数据绘制简单曲线图的完整步骤记录
Oct 30 Python
图神经网络GNN算法
May 11 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
Yii2增加验证码步骤详解
2016/04/25 PHP
php注册和登录界面的实现案例(推荐)
2016/10/24 PHP
PHP数组生成XML格式数据的封装类实例
2016/11/10 PHP
Thinkphp 3.2框架使用Redis的方法详解
2019/10/24 PHP
php操作redis命令及代码实例大全
2020/11/19 PHP
自动完成JS类(纯JS, Ajax模式)
2009/03/12 Javascript
Javascript实现视频轮播在pc端与移动端均可
2013/09/29 Javascript
JqueryMobile动态生成listView并实现刷新的两种方法
2014/03/05 Javascript
详解angular中通过$location获取路径(参数)的写法
2017/03/21 Javascript
Vue实现动态显示textarea剩余字数
2017/05/22 Javascript
详解关于html,css,js三者的加载顺序问题
2019/04/10 Javascript
jQuery内容选择器与表单选择器实例分析
2019/06/28 jQuery
SpringBoot+Vue 前后端合并部署的配置方法
2020/12/30 Vue.js
用Python实现QQ游戏大家来找茬辅助工具
2014/09/14 Python
Python 的 Socket 编程
2015/03/24 Python
python图像处理之反色实现方法
2015/05/30 Python
Python3中使用PyMongo的方法详解
2017/07/28 Python
python中的break、continue、exit()、pass全面解析
2017/08/05 Python
彻底搞懂Python字符编码
2018/01/23 Python
python3 对list中每个元素进行处理的方法
2018/06/29 Python
python 字符串只保留汉字的方法
2018/11/16 Python
Python微医挂号网医生数据抓取
2019/01/24 Python
python pandas写入excel文件的方法示例
2019/06/25 Python
TensorFlow——Checkpoint为模型添加检查点的实例
2020/01/21 Python
Django实现将一个字典传到前端显示出来
2020/04/03 Python
xadmin使用formfield_for_dbfield函数过滤下拉表单实例
2020/04/07 Python
美国百货齐全的精品网站,提供美式风格的产品:Overstock.com
2016/07/22 全球购物
澳大利亚最受欢迎的美发和美容在线商店:Catwalk
2018/12/12 全球购物
英国领先的游戏零售商:GAME
2019/09/24 全球购物
医药代表个人的求职信分享
2013/12/08 职场文书
项目资料员岗位职责
2013/12/10 职场文书
中学生期中自我鉴定
2014/04/20 职场文书
跳槽求职信范文
2014/05/26 职场文书
教师三严三实对照检查材料
2014/09/25 职场文书
大学开学典礼新闻稿
2015/07/17 职场文书
2015年中秋寄语
2015/07/31 职场文书