Sphinx和Python中的相对导入3.*

Jor*_*tao 10 python python-3.x python-sphinx

我有一个python包的目录,如下所示:

--docs/index.rst
--docs/...
--app/__init__.py
--app/foo.py
Run Code Online (Sandbox Code Playgroud)

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

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

sys.path.insert(0, os.path.abspath('../app'))
Run Code Online (Sandbox Code Playgroud)

cd进去docs/,跑

make html
Run Code Online (Sandbox Code Playgroud)

这给了我

SystemError:父模块''未加载,无法执行相对导入

所有具有的模块

from .foo import Bar
Run Code Online (Sandbox Code Playgroud)

我有一个干净的virtualenv安装Sphinx使用

pip install Sphinx
Run Code Online (Sandbox Code Playgroud)

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

我错过了什么?

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

aba*_*ert 14

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

如果你把一个包目录放在你身上sys.path,那么各种各样的事情都会出错.

我们来举个例子:

root/
    app/
        app/__init__.py
        app/spam.py
        app/eggs.py
Run Code Online (Sandbox Code Playgroud)

如果你有root你的sys.path(因为它是当前工作目录,或者是因为你这样做明确的,或者是因为你已经正确安装的东西到你site-packages),然后app是一个包,app.spam是一个模块,以及内app.eggs,.spam是该模块.一切顺利.

如果你有app你的sys.path,那么app不是一个包,spam是一个模块,而且,在其中eggs,.spam不是任何东西.所以,你不能使用相对导入.

如果你有两个在你的sys.path,然后app是包,spam并且app.spam都是不同的模块(具有相同的内容,执行两次),和内app.eggs,.spam是一个模块,但内eggs,.spam没有什么.这将导致您无法解决问题.


所以,很可能,你想要的修复是这样的:

sys.path.insert(0, os.path.abspath('..'))
Run Code Online (Sandbox Code Playgroud)

如果还有其他软件包或者不是软件包的Python代码目录..,你不想自动编写(例如,带有tests目录tests/test_spam.py),那么你需要重构你的目录以放入app一些目录其中没有任何其他Python代码,如下所示:

root/
    src/
        app/
    tests/
    doc/
Run Code Online (Sandbox Code Playgroud)

或者,如果你不想app成为一个包,而是想成为一个sys.path根目录,那么就杀掉它__init__.py,app直接离开sys.path.但在这种情况下,你不能使用包内相对进口; 所有模块app都是顶级模块,必须这样导入.


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

有关详细信息,请参阅3.3+,导入系统包含一切,组织良好; 对于旧版本,参考文档是泥泞,不完整和分散的; 你必须从The importstatement开始,然后阅读The Whoights Neeeow ... Wum ... Ping!(这基本上是一个PEP但1.5还没有PEP),甚至可能是ni文档,如果你能找到它,加上各种PEP和微小的变化日志条目,解释事情在1.5和2.7或3.2之间的变化或者等等.

  • @JCLeitão:如果你在Python 2.x中做同样的事情,那也是错误的.只有2.7才能让你在编写Python 1.5风格和Python-3.3风格之间的东西时有所作为,有时它可以... (2认同)