仅当从包中导入模块时,子目录导入才会出错

Subdirectory import giving error only when module gets imported from package

我有一个名为 classevivaAPI on PyPI (you can find it on GitHub here) 的软件包,出于显而易见的原因,我在我的计算机上克隆了一个 git


# main.py
from paths import paths
from variables.variables import *

main.py中,我有上面的import,当main.py是下面标记为已修改的文件(带有M)时。


我正在使用 test.py 测试此包,屏幕截图底部的 gitignored 文件包含以下内容:

#!\usr\bin\env python3
from classeviva import Session, Valutazioni, Note, Registro
from classeviva.variables import NoteSortBy

if __name__ == "__main__":
    # Some code here

classeviva 是包含在包 classevivaAPI 中的模块,而 test.py 是通过 pip 导入它的,我测试了它甚至给了我同样的问题如果从 src/ 很远的目录运行,通常 src/classeviva.

当我 运行 它给了我以下错误:

Traceback (most recent call last):
  File "d:\Python\Python\Classeviva\test.py", line 2, in <module>
    from classeviva import Session, Valutazioni, Note, Registro
  File "C:\Users\matti\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\classeviva\__init__.py", line 1, in <module>
    from .main import *
  File "C:\Users\matti\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\classeviva\main.py", line 3, in <module>
    from paths import paths
ModuleNotFoundError: No module named 'paths'

我很困惑,因为我遵循了here, here and expecially here的解释。


所以我想到了将test.pyif __name__ == '__main__'块复制粘贴到main.py的底部,令人惊讶的是它运行完美 没有给我任何错误。


有人知道发生了什么事吗?你有过这样的经历吗?你知道如何解决它或我做错了什么吗?

编辑


我在硬盘上包含所有 pip 安装模块的文件夹中搜索模块 (classeviva),我找到了它。

我打开它的 main.pyVisual Studio Code 智能感知告诉我和 CPython 之前一样的事情:没有名为 path 的子文件夹。

setup.py 文件缺少有关子模块的信息,我是这样添加的:

packages=[
    'classeviva',
    'classeviva.exceptions',
    'classeviva.paths',
    'classeviva.variables'
],
package_dir={
    '': 'src',
    'classeviva.exceptions': 'src/classeviva/exceptions',
    'classeviva.paths': 'src/classeviva/paths',
    'classeviva.variables': 'src/classeviva/variables',
},

我将 main.py import 更改为以下内容:

# main.py
from .paths import paths
from .variables.variables import *

需要 . 才能访问子目录。


现在一切正常。