Python包结构

时间:2011-04-21 17:24:07

标签: python packages

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

我以前必须解决这个问题,但我永远不会记得它应该如何完成。这对我来说并不直观。

2 个答案:

答案 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

  • 安装你的软件包,以便python可以从任何地方通过其绝对名称找到它(使用from myproject import models

选项B

  • 将相对父级添加到路径中的琐事
  • sys.path.append(os.path.abspath('..'))

建议使用前一个选项。