python解决导入的模块名称未定义好时的模块名称冲突

python解决导入的模块名称未定义好时的模块名称冲突,python,python-import,project-management,python-module,Python,Python Import,Project Management,Python Module,我在谷歌上搜索了很多,但找不到答案,我尝试过相对导入、使用别名(在当前项目或导入的模块init文件中)等方法。 为了方便地复制它,我检查了演示代码 回购协议有两个文件夹,A和B。它们被视为不同开发人员创建的不同项目。我将它们放在一个git回购中,因为它更容易用于演示目的 文件列表: . ├── A │   ├── init.py │   ├── foo_a.py │   └── utils_模块 │   ├── init.py │   └── utils.py ├── B

我在谷歌上搜索了很多,但找不到答案,我尝试过相对导入、使用别名(在当前项目或导入的模块init文件中)等方法。 为了方便地复制它,我检查了演示代码

回购协议有两个文件夹,AB。它们被视为不同开发人员创建的不同项目。我将它们放在一个git回购中,因为它更容易用于演示目的

文件列表:

.
├── A
│   ├── init.py
│   ├── foo_a.py
│   └── utils_模块
│   ├── init.py
│   └── utils.py
├── B
│   ├── init.py
│   ├── main.py
│   └── utils_模块
│   ├── init.py
│   └── utils.py
└── 自述文件

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

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

为了能够在B中导入A,我使用了
sys.path.append(A的相对或绝对路径)
。但在运行B时,会出现错误:

ImportError:无法导入名称“echo_a”

这个错误是合理的,因为A和B都有相同的模块名为
utils\u module/utils
(我也不想更改),而且B中的
utils
似乎已经覆盖了A的模块

如果在A中添加
\uuuu init\uuuu
文件,并在B.main.py中添加导入前缀
A.
,在A.foo\u A.py中使用相对导入(
from.
),则运行B可以获得正确的输出。但这次A不能像以前一样运行,错误

ModuleNotFoundError:没有名为“main.utils\u module”的模块; “main”不是包


那么如何通过改变导入语法来解决这个问题呢?谢谢

您希望将A和B视为包-因此在每个文件夹(A和B)中添加一个名为
\uuu init\uuuuuuuuuuupy的完全空文件

然后在B中,您将使用以下内容唯一地标识A的utils模块

从A.utils导入echo\u A
当您刚刚将每个目录添加到路径中,然后选择yes时,解释器首先找到的目录将覆盖utils模块。在包中结构化是模块化独立代码段的一种方法

然后,您可以从A和B上面的目录运行它,您可以运行类似于
python-mb.main



如果事情真的完成了,你也可以为a和B中的每一个建立一个setup.py,这样一个就可以使用pip安装另一个。

一种方法是将它分成3个项目,并为这两个项目创建第三个“通用”模块,包含
foo\u a
。谢谢,你的方法很好。但这增加了一种依赖性。A和B现在可以自己工作了,我很喜欢。你能澄清一下你在挣扎什么吗?如图所示,模块实际上是
A.utils
B.utils
(同样
A.foo\u A
B.main
),因此没有冲突。这些“包”实际上是完全设计为顶级的吗?如果是这样的话,在上游修复它们是最合理的做法。@MisterMiyagi在B中使用
sys.path.append()
时,utils模块的导入只会是
import utils
(或
from utils import echo_a
),这与它自己的UTIL冲突。当前目录和B的目录都有一个名为utils@MisterMiyagi我不太明白你的问题。这两个项目是分开设计的,它们被设计成不被其他代码导入。所以没有包名(或者你的顶级包也有相同的意思?)。如果我创建了一个永远不会被其他项目使用的项目,那么对我来说定义一个包名似乎毫无意义。我并不是在试图重构项目结构,因为我只是在询问可能性和语法,出于教育和学习的目的,最简单的解决方案是将A和B合并到一个公共模块中。但这不是这里的主题。谢谢。我为您的解决方案创建了一个分支演示。问题是,我必须更改A的代码以反映包名称的更改,我必须在foo_A.py中使用A.utils import echo_A的
,否则运行B.main.py将引发异常。除了添加init文件,我不想更改A的代码。从项目A的角度来看,给整个包命名似乎没有用。通常需要从您自己的包中导入东西,包括它自己的包名。这是对项目a包文件的一个很好的封装。您可以将导入更改为相对导入:
from.utils import echo_a
-但将a视为其他包(而非其本身)是很棘手的您的解决方案可以解决B导入a,但现在a本身出现以下错误:
modulenofounderror:没有名为“main.utils_module”的模块“main”不是包
。请查看我的更新代码。