我曾经认为,一旦加载了模块,如果其他文件导入了相同的模块,或者以不同的方式导入模块,则不会重新导入。例如,我的mdir/__init__.py
为空,mdir/mymod.py
为:
thenum = None
def setNum(n):
global thenum
if thenum is not None:
raise ValueError("Num already set")
thenum = n
def getNum():
if thenum is None:
raise ValueError("Num hasn't been set")
return thenum
来自同一文件的前几个用例根据期望进行。此文件为./usage.py
,文件夹mdir
位于:
import mdir.mymod
mdir.mymod.setNum(4)
print mdir.mymod.getNum()
from mdir import mymod
print mymod.getNum()
from mdir.mymod import *
print getNum()
try:
setNum(10)
except ValueError:
print "YHep, exception"
输出符合预期:
4
4
4
YHep, exception
但是,如果我弄乱系统路径,那么看起来模块会重新导入:
#BEHOLD
import sys
sys.path.append("mdir")
import mymod
try:
mymod.getNum()
except ValueError:
print "Should not have gotten exception"
mymod.setNum(10)
print mymod.getNum()
print mdir.mymod.getNum()
该代码在前一代码之后运行,产生:
Should not have gotten exception
10
4
是什么给出了?
答案 0 :(得分:4)
mymod
和mdir.mymod
被视为不同的模块 - 这里有一些相关的讨论:http://code.djangoproject.com/ticket/3951
<强>解释强>
最好与python交互式解释器一起玩,亲眼看看。我在某个目录下创建了目录(包)mydir
,在其中创建了两个文件(模块) - __init__.py
和mymod.py
,两者都是空的。我在包含mydir
的目录中启动了python。现在看看会发生什么:
>>> import mydir.mymod
>>> from mydir import mymod
>>> mymod == mydir.mymod
True
为什么mymod
和mydir.mymod
被视为同一件事?好吧,两个名称都引用相同的模块对象 - 模块的相等性由它们的路径比较决定:
>>> mymod
<module 'mydir.mymod' from 'mydir\mymod.py'>
>>> mydir.mymod
<module 'mydir.mymod' from 'mydir\mymod.py'>
现在,如果我改变sys.path
以包含mydir
并导入mymod
,导入模块的路径似乎会有所不同:< / p>
>>> import sys
>>> sys.path.append( "d:/zrodla/stack/mydir" )
# note that importing mymod (and not mydir.mymod) prior to appending mydir to
# path would cause an error
>>> mymod2
<module 'mymod' from 'd:/zrodla/stack/mydir\mymod.pyc'>
>>> mymod2 == mydir.mymod
False
然后生成的模块对象将不会比较相等。这样一个模块将被导入两次 - 这是正常的,这就是python的工作方式。请记住,导入的模块由其路径标识 - 更具体地说,我想是'虚线路径' - 查看sys.modules
键:
>>> [x for x in sys.modules.keys() if "my" in x]
['mydir', 'mymod', 'mydir.mymod']
我希望现在很清楚。