但還有另外一個(gè)問題 - 你以為你修改了某個(gè)變量,其實(shí),被from module import *后的那個(gè)并沒有被更新,非常危險(xiǎn),因?yàn)槌绦蛴锌赡苓€可以正常運(yùn)行, 只不過結(jié)果錯(cuò)了,到了production才被發(fā)現(xiàn)就比較慘了。
舉個(gè)例子:
你定義了一些變量在base模塊中:
# reference data type
class Demo:
def __init__(self, name):
self.name = name
demo = Demo('Demo')
# primitive type
foo = 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è)模塊中寫它:
import base
def 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))
然后先寫,后讀,看寫的內(nèi)容是否有效:
import read
import write
print "before write"
read.read()
write.write()
print "\nafter write"
read.read()
結(jié)論是沒有,原因是:
當(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還是指向原來那份內(nèi)存,原來的值
這個(gè)對(duì)于object,比較容易理解,你可以直接修改object里的值,這個(gè)是有效的,但是當(dāng)你指向另外一個(gè)object時(shí)就無效了。 對(duì)于primitive類型來講,其實(shí)也是一個(gè)道理,因?yàn)槊看钨x值,都是讓其指向一個(gè)不同的內(nèi)存地址,而不是inplace修改已有的那份內(nèi)存 -? 這個(gè)很容易驗(yàn)證:
In [1]: a = 10
In [2]: id(a)
Out[2]: 20429204
In [3]: a = 100
In [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
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元

