Python 访问分布在不同目录的模块包
我有一个关于一个模块的问题,这个模块分布在多个文件夹里。
假设我有这两个文件和文件夹:
~/lib/python
xxx
__init__.py
util
__init__.py
module1.py
module2.py
~/graphics/python
xxx
__init__.py
misc
__init__.py
module3.py
module4.py
然后在我的Python模块里,我这样做了:
import sys
pythonlibpath = '~/lib/python'
if pythonlibpath not in sys.path: sys.path.append(pythonlibpath)
import xxx.util.module1
这样是可以正常工作的。
现在,问题是我需要使用xxx.misc.module3,所以我这样做了:
import sys
graphicslibpath = '~/graphics/python'
if graphicslibpath not in sys.path: sys.path.append(graphicslibpath)
import xxx.misc.module3
但是我遇到了这个错误:
ImportError: No module named misc.module3
看起来它似乎还记得在~/lib/python里有一个xxx包,然后试图从那里找到misc.module3。
我该如何解决这个问题呢?
4 个回答
1
这个问题在Python 3.3中通过隐式命名空间包得到了处理。你可以查看一下PEP-420来了解更多信息。
1
Python 确实会记住曾经有一个 xxx
包。这是为了保证性能,因为一旦模块和包被加载,它们就会被缓存。你可以通过查看 sys.modules
这个字典来了解哪些模块已经被加载。
sys.modules
是一个普通的字典,所以你可以从中删除一个包,这样就可以强制它重新加载,像下面这样:
import sys
print sys.modules
import xml
print sys.modules
del sys.modules['xml']
print sys.modules
注意,在导入 xml
包后,它会出现在这个字典里,不过你也可以把它从字典中删除。这一点我提出来只是为了教学目的,我不建议在实际应用中使用这种方法。另外,如果你需要同时使用 misc
和 util
包,这样做可能就不太好。如果可以的话,最好调整你的源代码结构,以更好地适应 Python 的模块加载机制。
2
你不能这样做,除非使用非常复杂的手段把一个包的结构拉到另一个包里。Python要求一个包里的所有模块都必须放在同一个子目录下。想了解它是怎么处理的,可以看看os
的源代码,特别是os.path
是怎么工作的。