但還有另外一個(gè)問(wèn)題 - 你以為你修改了某個(gè)變量,其實(shí),被from module import *后的那個(gè)并沒(méi)有被更新,非常危險(xiǎn),因?yàn)槌绦蛴锌赡苓€可以正常運(yùn)行, 只不過(guò)結(jié)果錯(cuò)了,到了production才被發(fā)現(xiàn)就比較慘了。
舉個(gè)例子:
你定義了一些變量在base模塊中:
# reference data typeclass Demo: def __init__(self, name): self.name = namedemo = Demo('Demo')# primitive typefoo = 1然后在一個(gè)模塊中用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)
在另外一個(gè)模塊中寫(xiě)它:
import basedef 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))然后先寫(xiě),后讀,看寫(xiě)的內(nèi)容是否有效:
import readimport writeprint "before write"read.read()write.write()print "/nafter write"read.read()
結(jié)論是沒(méi)有,原因是:
當(dāng)你用from module import時(shí),其實(shí)是copy了一份reference或者pointer,指向一份內(nèi)存,var和module.var都指向同一份內(nèi)存
當(dāng)你修改module.var時(shí),其實(shí)你是讓它指向了另外一份內(nèi)存,此時(shí)var和module.var指向的是不同的內(nèi)存
所以,雖然module.var的值變了,var還是指向原來(lái)那份內(nèi)存,原來(lái)的值
這個(gè)對(duì)于object,比較容易理解,你可以直接修改object里的值,這個(gè)是有效的,但是當(dāng)你指向另外一個(gè)object時(shí)就無(wú)效了。 對(duì)于primitive類(lèi)型來(lái)講,其實(shí)也是一個(gè)道理,因?yàn)槊看钨x值,都是讓其指向一個(gè)不同的內(nèi)存地址,而不是inplace修改已有的那份內(nèi)存 - 這個(gè)很容易驗(yàn)證:
In [1]: a = 10In [2]: id(a)Out[2]: 20429204In [3]: a = 100In [4]: id(a)Out[4]: 20430108
所以,建議是除非是一個(gè)quick and dirty的腳本,否則不要使用from module import *!
例子: https://github.com/baiyanhuang/blog/tree/master/arena/python/from_module_import
|
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注