我有一个包含几个子包的Python包。
myproject/
__init__.py
models/
__init__.py
...
controllers/
__init__.py
..
scripts/
__init__.py
myscript.py
在myproject.scripts.myscript中,如何访问myproject.models?我试过了
from myproject import models # No module named myproject
import models # No module named models
from .. import models # Attempted relative import in non-package
我以前必须解决这个问题,但我永远不会记得它应该如何完成。这对我来说并不直观。
答案 0 :(得分:20)
这是正确的版本:
from myproject import models
如果它与ImportError: No module named foo
失败,那是因为您尚未设置PYTHONPATH
以包含包含myproject/
的目录。
我担心别人会建议让你避免设置PYTHONPATH
。我劝你不要理会他们。这就是PYTHONPATH
存在的原因:告诉Python在哪里查找要加载的代码。它功能强大,文档记录合理,可移植到许多环境中。人们玩耍以避免不得不设置它们。
即使没有设置PYTHONPATH
,显式相对导入 也能正常工作,因为它可以沿着目录层次结构向上走,直到找到正确的位置,它不需要找到顶部,然后走下去。但是,它在作为命令行参数传递给python
的脚本中不起作用(或者等效地,直接使用#!/usr/bin/python
行调用)。这是因为在这两种情况下,它都成为流程的__main__
模块。从__main__
开始无处可去 - 它已经位于顶部了!如果您通过导入该模块调用脚本中的代码,那么它就没问题了。也就是说,比较:
python myproject/scripts/myscript.py
到
python -c 'import myproject.scripts.myscript'
您可以通过不直接执行脚本模块来利用此功能,但创建执行导入的bin/myscript
并可能调用主函数:
import myprojects.scripts.myscript
myprojects.scripts.myscript.main()
比较Twisted的命令行脚本的定义方式:http://twistedmatrix.com/trac/browser/trunk/bin/twistd
答案 1 :(得分:2)
你的项目不在你的道路上。
选项A
from myproject import models
)选项B
sys.path.append(os.path.abspath('..'))
建议使用前一个选项。