import和from import都是將其他模塊導(dǎo)入當(dāng)前模塊中摹菠。
剛開始一直以為import和from import唯一的區(qū)別操刀,就是from import可以少寫一些模塊名乒验。雖然from XX import 會(huì)污染當(dāng)前名字空間俄认,但似乎僅限如此往毡。
但其實(shí)from import還有一個(gè)相當(dāng)嚴(yán)重的陷阱蒙揣。
舉例來說:
#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
結(jié)果為:
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
結(jié)果為:
python b.py
in a
2
3
4
如果,我們把a(bǔ).py中的test = 2修改為 test = [2]开瞭,后面對(duì)test的修改改為對(duì)test[0]的修改懒震,則會(huì)發(fā)現(xiàn),import和from import的結(jié)果完全一致嗤详。
通過以上的分析个扰。基本可以得到這樣的結(jié)論:
1 重復(fù)import或from import多次都只會(huì)作用一次
2 import和from import的作用機(jī)制完全不同
3 import的機(jī)制是將目標(biāo)模塊中的對(duì)象完整的引入當(dāng)前模塊葱色,但并不引入新的變量名
4 from import的機(jī)制則是通過引入新的變量名的形式递宅,將目標(biāo)模塊的對(duì)象的引用拷貝到新的變量名下的方式引入當(dāng)前模塊
這樣描述可能有點(diǎn)抽象,根據(jù)上面的例子來說就是:
1 當(dāng)使用import時(shí)苍狰,只存在一個(gè)名為a.test變量办龄,且只有這一個(gè),無論是在b模塊舞痰,還是c模塊中
2 當(dāng)使用from import時(shí)土榴,在b模塊中,存在一個(gè)新的變量b.test响牛,開始時(shí)玷禽,b.test = a.test(它們共同指向同一個(gè)對(duì)象)赫段,當(dāng)發(fā)生賦值時(shí),b.test指向了一個(gè)新的對(duì)象矢赁,但a.test仍指向原來的對(duì)象糯笙。
具體來說就是:
(1) 初始時(shí),在a中存在a.test變量撩银,它指向一個(gè)整數(shù)對(duì)象‘2’
(2) 在執(zhí)行b.py時(shí)给涕,from a import * 的執(zhí)行,相當(dāng)于引入了一個(gè)新的變量名b.test额获,b.test = a.test够庙,這時(shí),b.test和a.test都指向整數(shù)對(duì)象‘2’
(3) 之后的賦值操作(test = 3)抄邀,使得b.test = 3耘眨,使得b.test指向了整數(shù)對(duì)象'3',而a.test仍指向整數(shù)對(duì)象'2'
(4) 繼續(xù)執(zhí)行from c import * 時(shí)境肾,進(jìn)入c.py剔难,在c模塊中,執(zhí)行from a import *奥喻,將引入新的變量名c.test偶宫,c.test = a.test,它們都指向整數(shù)對(duì)象'2'环鲤,之后的賦值操作(test = 4),使得c.test = 4纯趋,現(xiàn)在,c.test指向了整數(shù)對(duì)象'4'楔绞,而a.test仍指向整數(shù)對(duì)象'2'
(5) 回到b.py结闸,由于b.test已存在唇兑,因此酒朵,不引人新的變量,而是直接執(zhí)行b.test = c.test扎附,這時(shí)蔫耽,b.test指向整數(shù)對(duì)象'4'
最終的結(jié)果,a.test指向'2'留夜,b.test指向'4'匙铡,c.test指向'4'
3 當(dāng)test變?yōu)閘ist時(shí),b.test[0]的修改碍粥,并沒有引起b.test本身的變化鳖眼,換言之,b.test和a.test仍指向同一個(gè)對(duì)象嚼摩,只不過這個(gè)對(duì)象內(nèi)部被修改了
總結(jié):
1 from import很危險(xiǎn)钦讳,如果不了解其作用機(jī)制矿瘦,慎用
2 即便知道了機(jī)制,一樣要慎用
(原時(shí)間2015-03-03)