Tom*_*ker 7 python python-module python-import pytest
假设我正在编写一个自定义 PIP 包,其结构如下:
\n.\n| setup.py\n\xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80 src\n| | __init__.py\n| | useful_functions_i.py\n| | useful_functions_ii.py\n| | useful_strings.py\n|\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80 tests\n | unit_tests.py\n\nRun Code Online (Sandbox Code Playgroud)\n假设useful_strings看起来像这样:
.\n| setup.py\n\xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80 src\n| | __init__.py\n| | useful_functions_i.py\n| | useful_functions_ii.py\n| | useful_strings.py\n|\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80 tests\n | unit_tests.py\n\nRun Code Online (Sandbox Code Playgroud)\n并且useful_functions_i和useful_functions_ii包含执行以下操作的函数:
USEFUL_STRING_A = "useful-string-a"\nUSEFUL_STRING_B = "useful-string-b"\n...\nRun Code Online (Sandbox Code Playgroud)\n我应该如何导入useful_stringsand ?useful_functions_iuseful_functions_ii(这并不是一个看起来那么简单的问题。)
如果我使用:
\ndef a_useful_function(a_string):\n if a_string == useful_strings.USEFUL_STRING_XYZ:\n return True\n return False\nRun Code Online (Sandbox Code Playgroud)\nsrc如果我尝试在本地运行一些代码,那么效果会很好;pip install .如果我运行并尝试将代码库用作 PIP 包,它将引发异常。
下一个替代方案是:
\nimport useful_strings\nRun Code Online (Sandbox Code Playgroud)\n如果我尝试使用代码库作为 PIP 包,这很有效。当我运行单元测试时,问题就出现了。我使用PyTest;我的pytest.ini开头是:
[pytest]\npythonpath = src\ntestpaths = tests\n...\nRun Code Online (Sandbox Code Playgroud)\n而且,如果我按照上面的定义编写单元测试a_useful_function(),相应的测试脚本将包含以下导入语法:
from . import useful_strings\nRun Code Online (Sandbox Code Playgroud)\n在这些条件下运行单元测试时,from . import useful_strings语法会引发异常。
我在这个网站上的另一个答案中发现了一个解决方法。(我忘记是哪一个了。)它看起来像这样:
\n[pytest]\npythonpath = src\ntestpaths = tests\n...\nRun Code Online (Sandbox Code Playgroud)\n这确实有效,并且它是一个遍布我当前正在处理的存储库中的解决方案。但它给人的感觉很老套、重复而且不符合Python风格。有更好的方法吗?(这也让 PyLint 抱怨导入订单,虽然我可以忍受这一点,但它变得令人恼火。)
\n我认为它只是“本地”运行您的代码(我认为这是您在从命令行开发/运行时使用的术语)这就是问题所在。我将使用以下语法来导入包:
from . import useful_strings
Run Code Online (Sandbox Code Playgroud)
但您需要确保 Python 在运行代码时知道您位于包中。所以运行类似的东西:
from . import useful_strings
Run Code Online (Sandbox Code Playgroud)
(即代替python src/entrypoint.py)你应该没问题。
我还建议使用“ src-layout ”或“ flat-layout ”,如setuptools 文档中所示。conftest.py在根目录中创建文件也可以帮助 pytest 找到源代码,因此测试也可以import my_package不引用src,请参阅https://docs.pytest.org/en/latest/explanation/pythonpath.html了解更多详细信息或在pytestPYTHONPATH中搜索conftest.py文件有什么用?。