import和from import都是將其他模塊導(dǎo)入當(dāng)前模塊中。
剛開(kāi)始一直以為import和from import唯一的區(qū)別,就是from import可以少寫(xiě)一些模塊名。雖然from XX import 會(huì)污染當(dāng)前名字空間,但似乎僅限如此。
但其實(shí)from import還有一個(gè)相當(dāng)嚴(yán)重的陷阱。
舉例來(lái)說(shuō):
#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é)果完全一致。
通過(guò)以上的分析?;究梢缘玫竭@樣的結(jié)論:
1 重復(fù)import或from import多次都只會(huì)作用一次
2 import和from import的作用機(jī)制完全不同
3 import的機(jī)制是將目標(biāo)模塊中的對(duì)象完整的引入當(dāng)前模塊,但并不引入新的變量名
4 from import的機(jī)制則是通過(guò)引入新的變量名的形式,將目標(biāo)模塊的對(duì)象的引用拷貝到新的變量名下的方式引入當(dāng)前模塊
這樣描述可能有點(diǎn)抽象,根據(jù)上面的例子來(lái)說(shuō)就是:
1 當(dāng)使用import時(shí),只存在一個(gè)名為a.test變量,且只有這一個(gè),無(wú)論是在b模塊,還是c模塊中
2 當(dāng)使用from import時(shí),在b模塊中,存在一個(gè)新的變量b.test,開(kāi)始時(shí),b.test = a.test(它們共同指向同一個(gè)對(duì)象),當(dāng)發(fā)生賦值時(shí),b.test指向了一個(gè)新的對(duì)象,但a.test仍指向原來(lái)的對(duì)象。
具體來(lái)說(shuō)就是:
(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]的修改,并沒(méi)有引起b.test本身的變化,換言之,b.test和a.test仍指向同一個(gè)對(duì)象,只不過(guò)這個(gè)對(duì)象內(nèi)部被修改了
總結(jié):
1 from import很危險(xiǎn),如果不了解其作用機(jī)制,慎用
2 即便知道了機(jī)制,一樣要慎用
(原時(shí)間2015-03-03)