【发布时间】:2020-10-12 10:16:51
【问题描述】:
我搜索了很多但找不到答案,我尝试了诸如相对导入、使用别名(在当前项目或导入的模块 init 文件中)等方法。 为了帮助轻松重现它,我检查了github 中的演示代码。
repo 有两个文件夹,A 和 B。它们被视为由不同开发人员创建的不同项目。我将它们放入一个单独的 git repo 中,因为这对您来说更容易演示目的。
文件列表:
.
├── 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: 没有名为 'main.utils_module' 的模块; 'main' 不是包
那么如何通过更改导入语法来解决这个问题?谢谢!
【问题讨论】:
-
一种方法是将其拆分为 3 个项目,并为两者制作第三个“通用”模块,其中包含
foo_a。 -
谢谢,你的方法有点好。但这增加了依赖。 A 和 B 目前可以自己动手,我喜欢。
-
你能澄清一下你在挣扎什么吗?如图所示,这些模块实际上是
A.utils和B.utils(同样是A.foo_a和B.main),所以没有冲突。 “包”实际上是否设计为完全*的?如果是这样,在上游修复它们是最合理的做法。 -
@MisterMiyagi 在 B 中使用
sys.path.append()时,utils 模块的导入将只是import utils(或from utils import echo_a),这与它自己的 utils 冲突。当前目录和 B 的目录都有一个名为 utils 的*模块 -
@MisterMiyagi 我不太理解你的问题。这两个项目是分开设计的,它们被设计成不被其他代码导入。所以没有包名(或者也许你的 top-level 包意味着同样的事情?)。如果我创建了一个永远不会被其他项目使用的项目,那么为我定义一个包名似乎毫无意义。而且我并不是要重构项目结构,因为我只是在询问可能性和语法,出于教育和学习的目的,最简单的解决方案是将 A 和 B 合并到一个通用模块中。但这不是这里的主题。
标签: python python-import project-management python-module