【发布时间】:2021-05-14 17:06:14
【问题描述】:
“什么是 PEP 兼容的方式来导入本地包,即使是从假设最少的父文件夹中导入”可能是长标题。我正在寻找一种可以使用本地软件包的解决方案。我的要求:
- 它必须与 PEP 兼容,即至少最普遍接受的 PEP 必须支持它
- 独立于操作系统、终端、用户和环境,即解决方案不得依赖于任何特定情况
在这些解决方案中,我正在寻找一种
- 实现起来最简单
- 修改范围灵活(不需要每次都执行,但不是永久的和系统范围的)
- 以最简单的形式保留源代码,即解决方案不需要在代码中添加很多额外的行
解决方案
到目前为止,这些是我在 SO 和其他地方找到的方法。它们都不适合我的需要,正如 8 年前所说的那样,every solution will have their cons。但我希望在 2021 年我们能找到至少满足我的两个要求的解决方案。
使用 conda
使用 conda 环境并通过 conda develop <path> 向 include a directory in the python lookup path 发出 conda,其中 <path> 可以是相对于 pwd 或绝对值。 Conda 然后在环境的site-packages 文件夹中创建一个conda.pth 文件,python 将提供该文件的内容,因此将在sys.path 中可用
缺点:它需要 conda-build,但并不总是存在。
使用点子
使用 pip 在本地安装软件包。创建一个setup.py,对其进行配置,cd 到它所在的位置,然后使用pip install -e . 以可编辑模式在本地安装包
缺点:PEP 517 不支持setuptools 中提到的可编辑安装。
直接破解sys.path
直接在python脚本中添加sys.path的路径,例如:
import os
import sys
sys.path.insert("path")
import mymodule
这里的路径可以是绝对的或相对的,后者可以是独立于操作系统的,例如通过使用os.path.sep。
缺点:它不兼容 PEP,因为并非所有导入语句都在文件顶部。 autopep8 会将您的代码重新排列成错误的顺序,但是,are workarounds。可以说这是一个可以忽略 PEP 的好例子,但我想相信导入足够基本,可以毫无例外地应用 PEP。
修改python路径
通过添加必要的目录来修改您的系统环境路径或pythonpath。
缺点:它至少依赖于操作系统并且过于全局,或者恰恰相反,需要每次都执行它。
使用相对导入
在脚本中,使用相对导入包含模块
from ..somewhere import mymodule
如果这个模块是主模块,这个不起作用,你会得到一个
ImportError: attempted relative import with no known parent package
此外,PEP 8 说:“非常不鼓励进行包内导入的相对导入。” Guido thinks it is ok.
相关问题
这不是重复关于如何在顶级之外导入模块的一般问题,因为这些问题已经得到了接受的答案。 SO 2, SO 3, SO 4, SO 5 SO 6, not even python
【问题讨论】:
-
“PEP 兼容”是什么意思?
-
如果至少最普遍接受的 PEP 通过明确建议或没有任何规则来支持它,则该解决方案是 PEP 兼容的。通过阅读描述非 PEP 兼容做法的“使用 pip”和“直接破解
sys.path”部分,您可以对此有更多了解。 -
是的,这还不清楚。例如,PIP 解决方案对我来说似乎是最正常的。但是您提到可编辑安装与该 PEP 不兼容,但我不明白这是怎么回事。此外,你为什么必须使用
-e? -
np8's answer 和 pytest's good integration practices 包含
-e开关。 Setuptools says 它不受支持,但我没有深入研究 PEP 以确定是否有办法与 PEP 见面。如果你能证明使用 pip 符合 PEP,我会很高兴。 -
@merv 我想出了我发现的解决方案来展示我的努力。欢迎任何进一步的解决方案或解释,我提供的清单并不详尽,也没有限制。例如。如果有人能解释为什么
pip -e是一种很好的做法,以及不鼓励这样做只是一种误解或过于简单化,那将是一个完美的解决方案。
标签: python import pip conda pep