导入一个导入模块的模块时遇到问题

Trouble importing a module that imports a module

我在使用 python 包时遇到问题,该包使用单独的模块来构建代码。包本身正在运行,但是当从另一个环境导入失败并出现 ModuleNotFound 错误时。 结构如下:

Project-root
|
|--src/
|    __init__.py
|    module_a.py
|    module_b.py
|    module_c.py
|    module_d.py
|--tests
etc.

在 module_a.py 我有:

from module_a import function_a1,...
from module_b import function_b1,...
from module_c import function_c1,...

在 module_c 我导入 module_d 如:

from module_d import function_d1,...

如上所述,直接从 CLI 执行 module_a 或 module_c 可以正常工作,我在测试目录中创建的单元测试也可以正常工作(借助 sys.path.insert),但是如果我创建一个新环境并导入包,我会收到以下错误:

>>> import module_a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/<abs_path>/.venv/lib/python3.9/site-packages/module_a.py", line 22, in <module>
    from module_c import function_c1, function_c2
  File /<abs_path>/.venv/lib/python3.9/site-packages/module_c.py", line 9, in <module>
    import module_d
ModuleNotFoundError: No module named 'module_d'
>>> 

除了将模块 c 和 d 的代码合并到一个文件中之外,我已经用尽了所有的想法来克服这个问题,或者重新考虑流程以便所有模块都从 module_a。 任何有关如何处理此问题的建议将不胜感激。 更新:原来是 setup.py 中 module_d 的名字打错了。无论出于何种原因 python setup.py install 无声地失败,或者我没有仔细阅读日志。

问题归结为了解 导入系统 PYTHONPATH.

的基础知识

当您尝试导入模块 (import module_a) 时,Python 将在 sys.path 中列出的每个目录中按顺序搜索。如果一个目录匹配名称 (module_a)1,那么它运行 __init__.py 文件是这样存在的。

当您得到一个 [https://docs.python.org/3/library/exceptions.html#ImportError] 时,这意味着 sys.path 中没有目录包含所要求的名称的目录。

你说你的测试你做了类似 sys.path.insert(0, "some/path/") 的事情,但这不是解决方案,只是一个错误的修复。

您应该做的是将您的 PYTHONPATH 环境变量设置为包含您的模块所在的目录,在您的例子中为 Project-root/src。这样,就无需在导入语句中使用 sys.path.insert 或 fiddle 和 relative/absolute 路径。

创建新环境时,只需将环境变量 PYTHONPATH 设置为包含 Project-root/src 即可。这就是安装常规 Python 模块(库)的工作方式:它们都放在 site-packages.

中的目录中

1:自旧 Python 版本以来发生了变化,目录过去需要包含 __init__.py 文件