我有一个包含几个子包的Python包.
myproject/
__init__.py
models/
__init__.py
...
controllers/
__init__.py
..
scripts/
__init__.py
myscript.py
Run Code Online (Sandbox Code Playgroud)
在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
Run Code Online (Sandbox Code Playgroud)
我以前必须解决这个问题,但我永远不会记得它应该如何完成.这对我来说并不直观.
Jea*_*one 20
这是正确的版本:
from myproject import models
Run Code Online (Sandbox Code Playgroud)
如果它失败,ImportError: No module named foo那是因为你没有设置PYTHONPATH包含包含的目录myproject/.
我担心其他人会建议让你避免设置的技巧PYTHONPATH.我劝你不要理会他们.这就是PYTHONPATH存在的原因:告诉Python在哪里寻找要加载的代码.它功能强大,文档记录合理,可移植到许多环境中.人们玩耍以避免不得不设置它们都不是这些.
即使没有设置,显式相对导入也可以工作PYTHONPATH,因为它可以沿着目录层次结构向上走,直到找到正确的位置,它不需要找到顶部然后向下走.但是,它在作为命令行参数传递的脚本中不起作用python(或者等效地,直接使用#!/usr/bin/python行调用).这是因为在这两种情况下,它都成为__main__该过程的模块.没有地方可以走到__main__- 它已经在顶部了!如果通过导入该模块来调用脚本中的代码,那么它就没问题了.也就是说,比较:
python myproject/scripts/myscript.py
Run Code Online (Sandbox Code Playgroud)
至
python -c 'import myproject.scripts.myscript'
Run Code Online (Sandbox Code Playgroud)
您可以通过不直接执行脚本模块来利用这一点,但创建一个bin/myscript导入并可能调用main函数的脚本模块:
import myprojects.scripts.myscript
myprojects.scripts.myscript.main()
Run Code Online (Sandbox Code Playgroud)
与Twisted的命令行脚本的定义相比:http://twistedmatrix.com/trac/browser/trunk/bin/twistd