【问题标题】:Sphinx and relative imports in Python 3.*Python 3.* 中的 Sphinx 和相关导入
【发布时间】:2013-11-27 19:07:32
【问题描述】:

我有一个包含python包的目录如下:

--docs/index.rst
--docs/...
--app/__init__.py
--app/foo.py

我正在使用带有 autodocs 的 sphinx 来记录应用程序(在 python 3.3 中)。

现在,在conf.py(在docs/ 内),我有

sys.path.insert(0, os.path.abspath('../app'))

我将cd 变成docs/,运行

make html

这给了我

系统错误:父模块''未加载,无法执行相对导入

对于所有具有

的模块
from .foo import Bar

我使用干净的虚拟环境安装了 Sphinx

pip install Sphinx

在我为 python 3.3 创建(干净的)环境之后。

我错过了什么?

发生这种情况时,我正在将项目从 python 2.* 移动到 python 3.*。所有的项目都在工作,但是这个......

【问题讨论】:

  • app 是一个顶级包本身,还是你的顶级包所在的目录?
  • 我不确定我是否理解您的问题@abarnert。 app里面没有目录,只有一组*.py,包括__init__.py。 sphinx 仅记录应用程序目录。
  • 如果app 里面有__init__.py,那么它就是一个包。这就是你的问题。让我写一个答案来解释。
  • 顺便说一句,你可能会混淆“包”这个词在 Python 中有两个相互冲突的含义:它是“一个你可以导入的东西,你可以在其中导入其他东西”,它也是“您放入 site-packages 或分发的东西,例如 PyPI"。

标签: python python-3.x python-sphinx


【解决方案1】:

您的app 目录是一个包。包是一个目录,里面有__init.py__ 和其他文件。

如果你把包目录放在你的sys.path上,各种事情都会出错。

举个例子:

root/
    app/
        app/__init__.py
        app/spam.py
        app/eggs.py

如果你的sys.path 上有root(因为它是你当前的工作目录,或者因为你明确地这样做了,或者因为你已经正确地安装了东西到你的site-packages),那么app 是一个包中,app.spam 是一个模块,而在 app.eggs 中,.spam 是那个模块。所以,一切正常。

如果你的sys.path 上有app,那么app 不是一个包,spam 是一个模块,并且在eggs 中,.spam 什么都不是。因此,您不能使用相对导入。

如果你的sys.path 上有both,那么app 是一个包,spamapp.spam 都是不同的模块(具有相同的内容,执行两次),并且在app.eggs 内,.spam 是一个模块,但在eggs 内,.spam 什么都不是。这会给你带来无穷无尽的问题。


因此,您想要的解决方法很可能是这样的:

sys.path.insert(0, os.path.abspath('..'))

如果在.. 中还有其他包或包含不是包的 Python 代码的目录(例如,tests 目录与 tests/test_spam.py),那么您将需要重组你的目录以将app 放入其中没有任何其他 Python 代码的目录中,如下所示:

root/
    src/
        app/
    tests/
    doc/

或者,如果您不希望 app 成为一个包,而是作为一个 sys.path 根目录,则杀死 __init__.py,并将 app 直接留在 sys.path 中。但在这种情况下,您不能使用包内相对导入; app 中的所有模块都是顶级模块,必须照此导入。


本教程的Packages 部分(以及上面一章的其余部分)解释了其中的一些内容,但那里可能有更好的介绍性文档。

有关详细信息,在 3.3+ 中,The import system 拥有一切,井井有条;对于旧版本,参考文档混乱、不完整且分散;你必须从The import statement开始,然后阅读The Knights Who Say Neeeow ... Wum ... Ping!(基本上是一个PEP,但1.5还没有PEP),甚至可能是ni文档,如果你能找到它,加上各种PEP和解释在 1.5 和 2.7 或 3.2 或其他版本之间发生了什么变化的微小更改日志条目。

【讨论】:

  • 很好的答案。谢谢你。你让我意识到我有很多关于新系统的知识。
  • @J.C.Leitão:如果你在 Python 2.x 中做同样的事情,那也是错误的。只是 2.7 让您可以轻松编写介于 Python 1.5 风格和 Python-3.3 风格之间的东西,而且有时它可以工作……
猜你喜欢
  • 2021-06-25
  • 2013-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-10
相关资源
最近更新 更多