绝对导入在使用pytest时可以正常工作,但在使用python运行时失败。

huangapple go评论68阅读模式
英文:

Absolute import works with pytest but fails when running with python

问题

Here is the translated content:

我将我的项目设置得与其他项目类似(例如NumpyPandas等,即使用项目名称作为目录):

目录结构:

/project_name
    project_name/
        utils/
            __init__.py
            utils.py
        tests/
            __init__.py
            test.py
        __init__.py

内容:

# /project_name/project_name/__init__.py  (空)

# /project_name/project_name/utils/__init__.py
from .utils import foo

# /project_name/project_name/utils/utils.py
def foo(x):
    return x

# /project_name/project_name/tests/test.py
from project_name.utils import foo

def test_foo():
    assert foo("1") == "1"

我的工作目录是/project_name,当我运行python project_name/tests/test.py时,出现了ImportError,但有趣的是,当我使用pytest时,导入正常工作:

$ cd /project_name

$ python project_name/tests/test.py
> ModuleNotFoundError: No module named 'project_name'

$ pytest
> =================== 1 passed in 1.76s ===================

我正在尝试遵循PEP8标准,使用绝对导入来处理脚本,并且不想修改sys.path或PYTHONPATH。我有点困惑为什么运行脚本会导致导入失败,而使用pytest时,导入正常工作。我的Python版本是3.10,如何组织项目以使运行python project_name/tests/test.py按预期工作?

额外的跟进问题,是否有PEP8关于脚本放置位置的最佳实践?我记得曾经看过将脚本放在包内是不推荐的做法,但找不到相关参考。如果有这方面的最佳实践,导入应该如何编写?

英文:

I setup my project similar to other projects (like Numpy and Pandas, i.e. using the project name as a directory):

Directory structure:

/project_name
    project_name/
        utils/
            __init__.py
            utils.py
        tests/
            __init__.py
            test.py
        __init__.py

Contents:

# /project_name/project_name/__init__.py  (empty)

# /project_name/project_name/utils/__init__.py
from .utils import foo

# /project_name/project_name/utils/utils.py
def foo(x):
    return x

# /project_name/project_name/tests/test.py
from project_name.utils import foo

def test_foo():
    assert foo("1") == "1"

My working directory is /project_name, when I run python project_name/tests/test.py I get an ImportError, but interestingly when I use pytest the import works just fine:

$ cd /project_name

$ python project_name/tests/test.py
> ModuleNotFoundError: No module named 'project_name'

$ pytest
> =================== 1 passed in 1.76s ===================

I'm trying to follow the PEP8 standard of using absolute imports for scripts and I do not want to have to modify sys.path or PYTHONPATH. I'm a bit confused why running the script causes the import to fail while when using pytest, the import works just fine. My python version is 3.10, how can I structure the project such that the running python project_name/tests/test.py works as expected?

Additional follow up, is there a PEP8 practice for where to place scripts? I recall reading that scripts inside a package is an anti-practice, but couldn't find any reference to this. If there is a practice for this, how would the imports be written?

答案1

得分: 1

Running python project_name/tests/test.py runs the module with an incorrect sys.path.

使用 -m 代替,以不影响 sys.path 运行该文件作为 __main__ 模块:

python -m project_name.tests.test

英文:

Running python project_name/tests/test.py runs the module with an incorrect sys.path.

Use -m instead to run that file as the __main__ module without touching sys.path:

python -m project_name.tests.test

</details>



huangapple
  • 本文由 发表于 2023年4月17日 14:14:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/76032154.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定