[英]Transitive import error: ModuleNotFoundError: No module named '…'
I'm confused now. 我现在很困惑。 Here is the project tree: 这是项目树:
project
- source
- - lib
- - - __init__.py
- - - utils.py
- - - stats.py
- test
- - lib
- - - test_stats.py
stats.py
has import utils
, which indeed works if one executes stats.py
itself. stats.py
有import utils
,如果执行stats.py
本身,它确实有效。 Now test_stats.py
has import lib.stats
but that results in the ModuleNotFoundError: No module named 'utils'
error if executed as PYTHONPATH=source pytest
in the project
directory: 现在test_stats.py
有import lib.stats
但是导致ModuleNotFoundError: No module named 'utils'
如果在project
目录中作为PYTHONPATH=source pytest
执行,则ModuleNotFoundError: No module named 'utils'
错误:
==================================== ERRORS ====================================
___________________ ERROR collecting test/lib/test_stats.py ___________________
ImportError while importing test module '/lib/test_stats.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
test/lib/test_stats.py:40: in <module>
import lib.stats
source/lib/__init__.py:42: in <module>
from .stats import Stats
source/lib/stats.py:40: in <module>
import utils
E ModuleNotFoundError: No module named 'utils'
!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!
=========================== 1 error in 0.19 seconds ============================
What's going on and how to properly execute tests with such directory structure? 发生了什么以及如何使用这样的目录结构正确执行测试?
PS I'm aware of (development mode) pip install ...
and tox
tricks (for module search path), but I would like to understand whether they are absolutely necessary to get this going or I already assume something wrong in this simple setup. PS我知道(开发模式) pip install ...
和tox
技巧(用于模块搜索路径),但我想了解它们是否绝对有必要实现这一目标,或者我已经假设在这个简单的设置中出错了。
import utils
in Python 3 is absolute import, Python looks module utils
in sys.path
. Python 3中的import utils
是绝对导入的,Python在sys.path
查找模块utils
。
When you run stats.py
as a script Python adds the directory project/source/lib/
to sys.path
. 当您将stats.py
作为脚本运行stats.py
,Python将目录project/source/lib/
到sys.path
。 So import utils
in the script works. 因此脚本中的import utils
可以工作。
But when you run test_stats.py
Python doesn't add project/source/lib/
to sys.path
. 但是当你运行test_stats.py
Python不会将project/source/lib/
到sys.path
。 So import utils
doesn't work. 所以import utils
不起作用。
A way to overcome that is to use relative import: from . import utils
克服这种情况的一种方法是使用相对导入: from . import utils
from . import utils
. from . import utils
。 In stats.py
it means: do not search sys.path
, import module utils
from the same directory as stats.py
. 在stats.py
它意味着:不要搜索sys.path
,从stats.py
目录中导入模块utils
。 But then you loose ability to run stats.py
as a script. 但是你失去了将stats.py
作为脚本运行的能力。 So move main code from stats.py
to a separate script outside of lib/
. 因此,将主要代码从stats.py
移动到lib/
之外的单独脚本。
A slightly different solution is to move main code from stats.py
to module __main__.py
and execute the module using python -m lib
( project/source/
must be in sys.path
). 稍微不同的解决方案是将主代码从stats.py
移动到模块__main__.py
并使用python -m lib
执行模块( project/source/
必须在sys.path
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.