【问题标题】:Transitive import error: ModuleNotFoundError: No module named '...'传递导入错误:ModuleNotFoundError:没有名为“...”的模块
【发布时间】:2018-09-02 09:15:52
【问题描述】:

我现在很困惑。这是项目树:

project
- source
- - lib
- - - __init__.py
- - - utils.py
- - - stats.py
- test
- - lib
- - - test_stats.py

stats.pyimport utils,如果自己执行stats.py,它确实有效。现在test_stats.py 具有import lib.stats,但如果在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 ============================

发生了什么以及如何正确执行具有这种目录结构的测试?

PS 我知道(开发模式)pip install ...tox 技巧(用于模块搜索路径),但我想了解它们是否是绝对必要的或者我已经假设这个简单的设置有问题。

【问题讨论】:

    标签: python python-3.x python-import pytest


    【解决方案1】:

    Python 3 中的import utils 是绝对导入,Python 在sys.path 中查找模块utils

    当您将stats.py 作为脚本运行时,Python 会将目录project/source/lib/ 添加到sys.path。所以脚本中的import utils 有效。

    但是当您运行test_stats.py 时,Python 不会将project/source/lib/ 添加到sys.path。所以import utils 不起作用。

    克服这个问题的一种方法是使用相对导入:from . import utils。在stats.py 中表示:不要搜索sys.path,从与stats.py 相同的目录导入模块utils。但是随后您失去了将stats.py 作为脚本运行的能力。因此,将主代码从 stats.py 移动到 lib/ 之外的单独脚本。

    稍微不同的解决方案是将主代码从stats.py 移动到模块__main__.py 并使用python -m lib 执行模块(project/source/ 必须在sys.path 中)。

    【讨论】:

    • 感谢您提供此信息;很有用。我实际上并不打算让stats.py 可执行,这只是为了演示。尽管如此,我不得不问你,在图书馆开发的这种情况下,什么才是真正的“最佳实践”?那么人们一般会做from . import utils吗?
    • numpy (fromnumeric.py),from . import ... 风格似乎是首选。
    • 这是一个值得商榷的问题。对于 stdlib PEP8 建议绝对导入(在您的情况下是 from lib import utils)。我知道也需要绝对进口的项目。我个人更喜欢相对导入。
    猜你喜欢
    • 2020-06-15
    • 1970-01-01
    • 2018-06-24
    • 2021-05-16
    • 2019-04-12
    • 2020-08-04
    • 1970-01-01
    • 2020-07-30
    • 2022-01-13
    相关资源
    最近更新 更多