python中from module import * 的一个陷阱
from module import *把module中的成员全部导到了当前的global namespace,访问起来就比较方便了。当然,python style一般不建议这么做,因为可能引起name conflict。
但还有另外一个问题 - 你以为你修改了某个变量,其实,被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中from module import * 的一个陷阱的更多相关文章
- Python中from module import *语法
from module import *的语法在Python 3.X和Python 2.X中的使用稍有区别: 在Python 3.X中,from module import *无法在函数里面使用,而在 ...
- 关于python中的module
python中的module(模块),关于这个概念以及使用时主要有以下几点需要注意: (1)import xx时,会首先将这个xx module中的代码执行一遍(且仅执行一遍): 例如: (2)模块包 ...
- Python中模块(Module)和包(Package)的区别
本文绝大部分内容转载至:廖雪峰官方网站 1. 模块(Module) 在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代码,我们把很多函 ...
- python中reload(module)的用法,以及错误提示
1.Python2中可以和Python3中关于reload()用法的区别. Python2 中可以直接使用reload(module)重载模块. Pyhton3中需要使用如下两种方式: 方式(1) ...
- python中:from * import 与 import 详解
在python 中导入模块是我们最常用的功能,基本每个.py 文件中都会有 import 或者是 from * import 语句,可是,这两种方法有什么不同,有该怎么用?今天就好好分析一下. 先上定 ...
- 关于python中模块的import路径
前两天被一个同事问了一个python的问题: 为什么一个目录里的python文件引用不要另一个兄弟目录的python文件,但是这两个目录的父母录运行时是可以引用到了.当时感觉一直是模块和包的机制问题, ...
- Python中list作为默认参数的陷阱
在Python中,作为默认参数的一定要是不可变对象,如果是可变对象,就会出现问题,稍不注意,就会调入陷阱,尤其是初学者,比如我(┬_┬). 我们来看一个例子. def add(L=[]): L.app ...
- python中类似c++静态方法的一个记录
个人学习c++出身,在后面的工作中接触到python,见到一些classmethod的字眼有点疑惑,所以进行一些记录. 都知道的是,c/c++中有着静态成员,静态方法的存在,比如: class A: ...
- python中全局变量和局部变量的一个小坑
python 中全局变量和局部变量在使用过程中的一个容易出错的地方 什么是全局变量 python中,在函数外部声明的变量可以叫做全局变量. x = 10 def fn1(): pass fn1() 什 ...
随机推荐
- Java成员的访问权限控制
Java中的访问权限控制包含两个部分: 类的访问权限控制 类成员的访问权限控制 对类来说,访问权限控制修饰符可以是public或者无修饰符(默认的包访问权限): 对于类成员来说,访问权限控制修饰符可以 ...
- Android中的单例模式
定义: 单例模式:确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 使用场景: 确保某一个类有且只有一个对象的场景,避免产生多个对象消耗过多的资源,或者某种类型的对象只应该有且只有一 ...
- jsp有哪些内置对象?作用分别是什么?分别有什么方法?
JSP共有以下9个内置的对象: request 用户端请求,此请求会包含来自GET/POST请求的参数 response 网页传回用户端的回应 pageContext 网页的属性是在这里管理 sess ...
- WIN7管理工具配置ODBC数据源-系统DSN中无Oracle,Sybase驱动的解决方法
在C:\Windows\SysWOW64下找到: odbcad32.exe 这个文件,双击打开. 点击添加按钮,选择 对应的 驱动,然后就可用添加连接Oracle/Sybase的ODBC的数据源了.
- ThreadPoolExecutor-线程池开发的使用
好久没有写过笔记了,最近做的一个项目涉及打线程池和队列的开发,觉得在这个项目中学习到的还是挺多的,对线程安全,并发的知识有加深认知:当然,现在用过的东西并不是代表以后还能娴熟的使用,做好笔记非常重要: ...
- Redhat使用CentOS的Yum 网络源
Redhat 的更新包只对注册的用户生效,所以我们自己手动更改成CentOS 的更新包,CentOS几乎和redhat是一样的. 1.首先查看redhat 7.0系统本身所安装的那些yum 软件包:[ ...
- 在Python命令行和VIM中自动补全
作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/ 1. VIM下的配置: wget https://github.com/rkulla/pydiction/arc ...
- Java报表FineReport在医院院长查询分析系统中有什么用
1.医院院长查询系统的价值 目前,大中型医院的信息处理正从传统手工方式飞速向电脑信息化建设方案转变,一个大中型医院担负着繁重的医疗和科研任务,以及繁杂的事务性工作,院长必须时刻与各科室保持密切的连续, ...
- NOIP2010普及组题解 -SilverN
三国游戏 题目内容不放了 由于电脑总是会拆掉最大的组合,所以玩家最多只能得到数值第二大的组合 那么找出第二大的组合就行了 #include<iostream> #include<cs ...
- 最新discuz模版制作7堂课让你精通discuz模版制作
第一课 基本知识储备一.基本 HTML 代码二.网站语言编码 三.DIV+CSS 认知及应用 第二课 必备软件.环境配置及程序安装 第三课 DISCUZ 构架详解 一.DISCUZ 基础构架讲 ...