Sphinx-doc出现“尝试相对导入”的错误

5
我是一名有用的助手,可以为您翻译文本。
我尝试使用Sphinx-doc的自动文档功能。我想解决以下问题。目前,来自StackOverflow的解决方案都没有起作用。这是由于我的项目结构还是我选择导入模块的方式所致?
给出文件的结构:
project
 |_ src
 |   |_ pre_processing
 |   |     |_ fileInfo.py
 |   |
 |   |_ utils
 |         |_ folder.py
 |_ test
 |      
 |_ doc
 |   |_ doc_user
 |        |_ build
 |        |_ source
 |             |_config.py

以下是 config sys.path :

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

我在fileInfo.py中有一些相对导入,如下:

from ..utils.folder import get_files_directory

终端错误
WARNING: autodoc: failed to import module 'pre_processing.fileInfo'; the following exception was raised:
Traceback (most recent call last):

File "/home/florian-stage/miniconda/envs/gd/lib/python3.5/site-packages/sphinx/ext/autodoc/importer.py", line 140, in import_module
__import__(modname)

File "/home/florian-stage/Projet-2018/pg_georef_data-master/arbo propre/src/pre_processing/fileInfo.py", line 12, in <module>
from ..utils.folder import get_files_directory
ValueError: attempted relative import beyond top-level package

相对导入适用于包。您似乎没有任何包(没有 __init__.py(c) 文件存在)。 - CristiFati
我以为在 Python 3.* 中我们不需要它了? - floriandaniel
你的Sphinx配置文件命名为config.py吗?通常的名称是conf.py。请参阅http://www.sphinx-doc.org/en/master/usage/configuration.html。 - mzjn
1
这个问题解决了吗?似乎添加__init__并不能解决这个问题。 - Jiadong
3个回答

2

我知道这是一个旧问题,但是,你解决了吗?

如果有人在Sphinx和相对导入方面遇到问题,我建议尝试以下方法(按照此问题的初始示例):

  1. 在config.py中进行替换:

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

改为

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

  1. 如果您正在使用autodoc,则必须更改.rst文件,例如:

.. automodule:: pre_processing.fileInfo

改为:

.. automodule:: src.pre_processing.fileInfo

注意:无需创建__init__.py文件,因为我可以在之前的答案中读取。

问候。


0

看起来你的问题与项目结构有关。正如CristiFati所建议的那样,你应该在每个文件夹中都有一个__init__.py文件,包括project有关包的文档认为这是必要的:

init.py文件是必需的,以使Python将目录视为包含包;这是为了防止具有公共名称(例如string)的目录无意中隐藏后面出现的有效模块。

为了测试你的代码,你需要从某个main.py文件运行,因为导入将相对于顶级文件夹(在这种情况下是project)。以下是文件结构应该如何看起来的示例:

project
 |  __init__.py
 |  main.py
 |_ src
 |   |  __init__.py
 |   |_ pre_processing
 |   |     |  __init__.py
 |   |     |  fileInfo.py
 |   |
 |   |_ utils
 |         |  __init__.py
 |         |  folder.py
 |_ test
 |   |  __init__.py
 |      
 |_ doc
 |   |  __init__.py
 |   |_ doc_user
 |        |  __init__.py
 |        |_ build
 |             |  __init__.py
 |        |_ source
 |             |  __init__.py
 |             |  config.py

然后在 main.py 文件中你应该有如下代码:

from src.pre_processing import fileInfo

运行main.py现在应该会产生无错误的输出。


在假设doc目录包含Sphinx项目的情况下,添加__init__.py文件是没有意义的。Sphinx项目有一个conf.py文件,但不需要任何__init__.py文件。 - mzjn

0
项目根目录而不是源目录添加到sys.path中似乎可以解决该问题。请记得添加__init__.py文件来声明包。
之后,您还应该修改*.rst文件中模块的引用,加上前缀src

示例:

#  in "doc/doc_user/source/config.py"
import os
# ("../../..") instead of ("../../../src")!
sys.path.insert(0, os.path.abspath("../../.."))

__init__.py中的示例定义

#  in "src/utils/__init__.py"
from .folder import get_files_directory

导入 fileInfo。具体操作可能因为你是否导入 get_files_directory__init__.py 中而有所不同。

# in "src/pre_processing/fileInfo.py"
from ..utils import get_files_directory

在任何*.rst文件中的引用应该看起来像这样。(在前面加上src

.. automodule:: src.pre_processing.fileInfo
  :members:

project
 ├── src
 │   ├── __init__.py
 │   ├── ...
 │   ├── pre_processing
 │        ├── __init__.py
 │        ├── fileInfo.py
 │   └── utils
 │        ├── __init__.py
 │        └── folder.py
 ├── test
 ├── doc
 │   └── doc_user
 │        ├── build
 │        └── source
 │             ├── config.py
 │             └── ...

另一个示例是在一个单独的目录中使用sphinx文档。

#  in "docs/conf.py"
import os
# ("..") instead of ("../src")!
sys.path.insert(0, os.path.abspath(".."))

project
 ├── src
 ├── test
 ├── docs
 │    ├── _static
 │    ├── _templates
 │    ├── ...
 │    ├── index.rst
 │    └── conf.py
 ├── ...
 ├── setup.cfg
 └── setup.py

参考资料

  1. 导入系统
  2. Python模块和包 - 简介
  3. 隐式命名空间包

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接