未正确定义导入的模块名称时,python解析模块名称冲突

问题描述

我在Google上搜索了很多,但是找不到答案,我尝试了使用别名(相对导入),使用别名的方法(在当前项目中或在导入的模块 init 文件中)。 为了帮助轻松重现它,我检查了github中的演示代码

存储库有两个文件夹, A B 。它们被视为由不同开发人员创建的不同项目。我将它们放入一个单独的git repo中,因为对于 demo目的来说,这对您来说更容易。

文件列表:


├──A
│├── init .py
│├──foo_a.py
│──└──utils_module
│├── init .py
│└──utils.py
├──B
│├── init .py
│├──main.py
│──└──utils_module
│├── init .py
│└──utils.py
└──README.md

A和B都有其主要入口,并且可以成功运行(只需引用其utils,然后回显A或B)。

现在的问题是,A有一些功能foo_a)可以(但不能设计为)由B重用,因此B需要导入它。但是我不想将两个项目合并为一个,因为它们是分开开发的。重构A的文件夹/包结构也不在这个问题的范围内(除非在 init 添加一些代码,如果有帮助的话)。你问我为什么,我只是在学习python的导入机制。

为了能够在B中导入A,我使用sys.path.append(A's relative or absolute path)。但是在运行B时,会出现错误

ImportError:无法导入名称'echo_a'。

错误是合理的,因为A和B都具有名为utils_module/utils的相同模块(我也不想更改),并且似乎B中的utils已覆盖A的模块。

如果在A中添加__init__文件,并在B.main.py中添加导入前缀A.,并在A.foo_a.py中使用相对导入(from .),然后运行B可以获得正确的输出。但这一次A无法像以前一样运行,错误

ModuleNotFoundError:没有名为“ .utils_module”的模块; “ 主要”不是软件包

那么如何通过更改导入语法来解决此问题?谢谢!

解决方法

您希望将A和B视为包-因此在每个文件夹(A和B)中,您将添加一个名为__init__.py的完全空文件。

然后在B中,您将用类似的东西唯一地标识A的utils模块

from A.utils import echo_a

当您只是将每个目录添加到路径时,是的,无论是哪个解释器首先找到,utils模块都会被覆盖。构建软件包是模块化隔离代码段的一种方法。

然后,您将在A和B上方的目录中运行此方法,运行类似python -m B.main


如果确实构建了东西,您还可以为A和B中的每一个建立一个setup.py,并使其可以使用pip来安装另一个。