我有一个带有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
给了我
SystemError:未加载父模块,无法执行相对导入
到具有
的所有模块from .foo import Bar
我使用
安装了Sphinx的干净virtualenvpip install Sphinx
为python 3.3创建(干净)环境后。
我错过了什么?
我正在将项目从python 2. *移动到python 3. *当发生这种情况时。所有项目都在运作,但是......
答案 0 :(得分:14)
您的app
目录是一个包。包是一个包含__init.py__
的目录,其中包含其他文件。
如果您在sys.path
上放置了一个包目录,那么各种各样的事情都会出错。
我们举一个例子:
root/
app/
app/__init__.py
app/spam.py
app/eggs.py
如果root
上有sys.path
(因为它是您当前的工作目录,或者是因为您明确地这样做了,或者因为您已正确安装了site-packages
),然后app
是一个包,app.spam
是一个模块,在app.eggs
中,.spam
是该模块。一切顺利。
如果app
上有sys.path
,那么app
不是一个包,spam
是一个模块,并且在eggs
内.spam
1}}不是什么。所以,你不能使用相对导入。
如果sys.path
上有两者,那么app
是一个包,spam
和app.spam
都是不同的模块(使用相同的内容,执行两次),并且在app.eggs
内,.spam
是一个模块,但在eggs
内,.spam
不是任何内容。这将导致你无法解决问题。
所以,最有可能的是,您想要的修复是这样的:
sys.path.insert(0, os.path.abspath('..'))
如果有其他软件包或者不是软件包的Python代码的目录,则..
中您不想自动分区(例如,tests
目录{{1}然后你需要重新构建你的目录,把tests/test_spam.py
放到一个没有任何其他Python代码的目录中,如下所示:
app
或者,如果您不希望root/
src/
app/
tests/
doc/
成为一个包,而是希望成为一个sys.path根目录,那么请终止app
,并将__init__.py
直接保留在app
。但在这种情况下,你不能使用包内相对进口; sys.path
中的所有模块都是顶级模块,必须按原样导入。
本教程的Packages部分(以及上面章节的其余部分)解释了其中的一些内容,但可能有更好的介绍性文档。
有关详细信息,请参阅3.3+,The import system包含所有内容,组织良好;对于旧版本,参考文档是泥泞,不完整和分散的;你必须从The import
statement开始,然后阅读The Knights Who Say Neeeow ... Wum ... Ping!(这基本上是一个PEP但1.5还没有PEP),甚至可能是app
文档,如果你能找到的话它,以及各种PEP和次要变更日志条目,解释事情在1.5和2.7或3.2或其他任何事情之间的变化。