导入一个导入模块的模块时遇到问题
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
文件
我在使用 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
文件