python 包的相对导入问题

Relative import problem with python packages

首先,我已经浏览了很多关于这个问题的问答,但我找不到解决我的问题的方法。


我使用的是 Python 3.7.9,我的文件结构如下所示

generator/
    __init__.py
    main.py
    summarygenerator/
        __init__.py
        utils.py
        summary_generator.py

summary_generator.py长得像

from summarygenerator.utils import solver

def sum_gen():
   pass
if __name__ == '__main__':
   sum_gen()

通过这种方法,我可以从“generator”目录中 运行 main.py 使用:

python main.py

和summary_generator.py以及

python -m summarygenerator.summary_generator

但是,当我想从 generator/summarygenerator 目录中 运行 summary_generator.py 时,我会遇到:

ModuleNotFoundError: No module named summarygenerator

下面的相对导入也没有解决问题。

from .utils import solver

因此,该错误非常明显,因为您尚未声明名为 summarygenerator 的模块。由于 utils 与您的 summary_generator 代码位于同一模块中,您可以尝试像下面那样直接导入,因为 Python's module search path starts with the current directory

from utils import solver

解决您的问题的其他方法(通常当 utils 位于不同的模块中时)是打包您的应用程序并显式声明您的模块,或者考虑设置 PYTHONPATH 以包含您想要的模块。

Python 模块意味着 运行 来自其根目录的父目录 包裹。因此 运行 脚本的正确方法是(从生成器目录开始):

$ cd ..
$ python -m generator.main
$ python -m generator.summarygenerator.summary_generator

导入意味着开箱即用,您甚至可以使用相对导入。现在您似乎希望能够 运行 python 脚本使用来自两个不同位置的相同代码开箱即用(使用相同的代码)。那是不受支持的,确实没有意义。在导入的情况下,这意味着 python 应该能够以 两种 不同的方式记录模块的名称,并且所有内容(所有其他模块名称)都应该使用这两个名称.或者采用(更简单的)在文件中定义相对路径的情况(如 open('some_file'))——如果文件以两种方式 运行,这就注定了。在这两种情况下,问题都是当前工作目录的变化——脚本 运行 来自的目录被设置为相对于计算路径(包括模块路径)的当前工作目录。您可以通过弄乱当前的工作目录并创建更多微妙的错误来使这个“运行 来自任何文件夹的我”工作 - 或者(这就是我认为的答案)停止尝试能够 运行 来自不同文件夹的相同脚本,编写导入,以便它们使用上面的命令,这是 运行 宁一个 python 脚本的推荐方式(所以所有关于导入的文档都采用这种方式 运行宁它)