python import和from import

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)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • python import 和from import 區(qū)別,以及在mock中的應(yīng)用 前言 寫(xiě)python肯定會(huì)使用...
    茫子閱讀 3,614評(píng)論 0 1
  • 1.埋點(diǎn)是做什么的 2.如何進(jìn)行埋點(diǎn) 3.埋點(diǎn)方案的設(shè)計(jì) 近期常被問(wèn)到這個(gè)問(wèn)題,我擔(dān)心我的答案會(huì)將一些天真爛漫的孩...
    lxg閱讀 2,327評(píng)論 0 1
  • Python語(yǔ)言特性 1 Python的函數(shù)參數(shù)傳遞 看兩個(gè)如下例子,分析運(yùn)行結(jié)果: 代碼一: a = 1 def...
    伊森H閱讀 3,175評(píng)論 0 15
  • 愛(ài)情這件事,總是讓人摸不著頭腦。你永遠(yuǎn)不知道它什么時(shí)候會(huì)來(lái),但它又隨時(shí)可能會(huì)出現(xiàn)。 有些人雖然喜歡你,但不一定會(huì)說(shuō)...
    小熊敘情閱讀 786評(píng)論 0 1
  • 1、父類實(shí)現(xiàn)深拷貝時(shí),子類如何實(shí)現(xiàn)深度拷貝。父類沒(méi)有實(shí)現(xiàn)深拷貝時(shí),子類如何實(shí)現(xiàn)深度拷貝。 深拷貝同淺拷貝的區(qū)別:淺...
    Mr丶炎閱讀 131評(píng)論 2 0

友情鏈接更多精彩內(nèi)容