python import和from import
admin
2023-07-30 20:45:00
0

import和from import都是将其他模块导入当前模块中。
刚开始一直以为import和from import唯一的区别,就是from import可以少写一些模块名。虽然from XX import 会污染当前名字空间,但似乎仅限如此。
但其实from import还有一个相当严重的陷阱。
举例来说:

#a.py
test = 2
print \'in a\'
#b.py
from a import *
print test
test = 3
from c import *
print test
#c.py
from a import *
print test
test = 4

结果为:

python b.py
in a
2
2
4

如果将代码修改如下:

#a.py
test = 2
print \'in a\'
#b.py
import a
print a.test
a.test = 3
import c
print c.a.test
#c.py
import a
print a.test
a.test = 4

结果为:

python b.py
in a
2
3
4

如果,我们把a.py中的test = 2修改为 test = [2],后面对test的修改改为对test[0]的修改,则会发现,import和from import的结果完全一致。

通过以上的分析。基本可以得到这样的结论:
1 重复import或from import多次都只会作用一次
2 import和from import的作用机制完全不同
3 import的机制是将目标模块中的对象完整的引入当前模块,但并不引入新的变量名
4 from import的机制则是通过引入新的变量名的形式,将目标模块的对象的引用拷贝到新的变量名下的方式引入当前模块

这样描述可能有点抽象,根据上面的例子来说就是:
1 当使用import时,只存在一个名为a.test变量,且只有这一个,无论是在b模块,还是c模块中
2 当使用from import时,在b模块中,存在一个新的变量b.test,开始时,b.test = a.test(它们共同指向同一个对象),当发生赋值时,b.test指向了一个新的对象,但a.test仍指向原来的对象。
具体来说就是:
(1) 初始时,在a中存在a.test变量,它指向一个整数对象‘2’
(2) 在执行b.py时,from a import * 的执行,相当于引入了一个新的变量名b.test,b.test = a.test,这时,b.test和a.test都指向整数对象‘2’
(3) 之后的赋值操作(test = 3),使得b.test = 3,使得b.test指向了整数对象\’3\’,而a.test仍指向整数对象\’2\’
(4) 继续执行from c import * 时,进入c.py,在c模块中,执行from a import *,将引入新的变量名c.test,c.test = a.test,它们都指向整数对象\’2\’,之后的赋值操作(test = 4),使得c.test = 4,现在,c.test指向了整数对象\’4\’,而a.test仍指向整数对象\’2\’
(5) 回到b.py,由于b.test已存在,因此,不引人新的变量,而是直接执行b.test = c.test,这时,b.test指向整数对象\’4\’
最终的结果,a.test指向\’2\’,b.test指向\’4\’,c.test指向\’4\’
3 当test变为list时,b.test[0]的修改,并没有引起b.test本身的变化,换言之,b.test和a.test仍指向同一个对象,只不过这个对象内部被修改了

总结:
1 from import很危险,如果不了解其作用机制,慎用
2 即便知道了机制,一样要慎用
(原时间2015-03-03)

相关内容

热门资讯

500 行 Python 代码... 语法分析器描述了一个句子的语法结构,用来帮助其他的应用进行推理。自然语言引入了很多意外的歧义,以我们...
定时清理删除C:\Progra... C:\Program Files (x86)下面很多scoped_dir开头的文件夹 写个批处理 定...
65536是2的几次方 计算2... 65536是2的16次方:65536=2⁶ 65536是256的2次方:65536=256 6553...
Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
scoped_dir32_70... 一台虚拟机C盘总是莫名奇妙的空间用完,导致很多软件没法再运行。经过仔细检查发现是C:\Program...
pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
python绘图库Matplo... 本文简单介绍了Python绘图库Matplotlib的安装,简介如下: matplotlib是pyt...
Prometheus+Graf... 一,Prometheus概述 1,什么是Prometheus?Prometheus是最初在Sound...
微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...