如何在 Python 包中使用相对导入,尤其是在 pytest 中?

问题描述 投票:0回答:1

如果之前有人问过这个问题,我深表歉意,但我找不到这个问题的唯一明确答案,而且每个人的答案似乎都略有不同。我已经检查了相当多的文档,但我似乎在这个过程中有点疯狂,现在质疑关于 python 导入的基本事实。

我制作了几个 Python 包,但我一直在努力让导入工作。我的正常项目结构(在 Python 打包用户指南 中给出)如下:

packageName/
    src/
        packageName/
            __init__.py
            file1.py
            file2.py
        tests/
            test_file1.py
            test_file2.py
            testData/
                data_for_tests.py

目前,当我想在

file2.py
中使用
file1.py
中的函数时,我会使用
from .file2 import functionName
,但这看起来非常笨拙和不优雅,并且消除了在文件后面抽象事物的很多好处。我也读过很多文件说这些相对进口被认为是有害的。

我试过只使用

import packageName.file2
,但是当我运行 pytest 时它告诉我不存在这样的包。我能想到的唯一解决方法是设置一个脚本以将其构建到轮子中并首先在本地安装,但这似乎不是特别优雅。作为参考,当我运行 pytest 时,我通过从包根目录运行
python3 -m pytest
来完成。

此外,当我想要一个函数(比如来自

file1
)作为
packageName.function
使用时,我将
from file1 import function
放入init文件中。这似乎没问题,但是考虑到所有这些其他的东西,我想知道这是否是正确的方法。

我和很多使用 Python 的工程师一起工作,但他们都没有制作 pip 上的包,这似乎是最好的答案。

编辑以添加我的特殊情况:

在Blue Robin的建议下,我尝试只使用

from packageName import file2
,它在一个文件上有效,但在使用其他文件时不起作用(虽然我确定这不是循环依赖问题)。作为一个更具体的例子,这是我目前正在从事的项目:

countach/
    src/
        countach/
            __init__.py
           fileops.py     | (no imports)
           fixed.py       | (no imports)
           processing.py  | (imports fileops and types)
           types.py       | (imports fixed)

我将

from .fileops import _function
替换为
from countach import fileops
,它起作用了(从给定函数中删除了下划线)。然后我尝试使用其他导入,但它们没有用,给出了错误
ImportError: cannot import name 'types' from 'countach'
(或与
fixed
相同类型的错误)。谷歌搜索这些错误表明它们通常发生在循环依赖中,但事实并非如此,因为
fixed
不导入任何东西。我什至尝试从同一目录中的 python3 REPL 执行此操作,但它给出了相同的错误。

我非常感谢您在这里免费抽出时间,所以我不希望任何人仔细研究任何事情,但我们将不胜感激任何帮助。

python import packaging
1个回答
0
投票

如何从目录导入函数、类和其他 python 文件

from directory import file  # file is the .py file name within the directory
from file import class  # You can replace class with any function or class in the py file

什么是 ImportError: cannot import name 'types from 'countach'##

  1. 这可能不是循环导入错误,但如果是,您可以找到更多相关信息here
  2. 可能是拼写错误
  3. 您尝试导入的结构可能是错误的。

例如:

from dir import file

File structure:
dir-
-- file1
dir2-
--file

如您所见,文件在 dir2 而不是 dir.

我相信这是第二期,但我没有足够的信息。

© www.soinside.com 2019 - 2024. All rights reserved.