Python包结构

16 python packages

我有一个包含几个子包的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