我尝试阅读有关同级导入甚至 包文档的问题,但是我还没有找到答案。
具有以下结构:
├── LICENSE.md ├── README.md ├── api │ ├── __init__.py │ ├── api.py │ └── api_key.py ├── examples │ ├── __init__.py │ ├── example_one.py │ └── example_two.py └── tests │ ├── __init__.py │ └── test_one.py
examples和tests目录中的脚本如何 从api模块导入 并从命令行运行?
examples
tests
另外,我想避免sys.path.insert每个文件的难看。当然可以在Python中完成,对吗?
sys.path.insert
自从我在下面写下答案以来,修改sys.path仍然是一种快速技巧,适用于私有脚本,但是有一些改进
sys.path
安装该软件包(无论是否在virtualenv中)都将为您提供所需的内容,尽管我建议使用pip进行操作,而不要直接使用setuptools(并setup.cfg用于存储元数据) 使用该-m标志并作为软件包运行也可以(但是如果要将工作目录转换为可安装的软件包,将会有些尴尬)。 对于测试,特别是pytest能够在这种情况下找到api程序包,并sys.path为您解决问题 因此,这实际上取决于您要做什么。但是,就您而言,既然您的目标似乎是在某个时候制作一个合适的程序包,那么通过安装pip -e可能是您的最佳选择,即使尚不完美。
setuptools
旧答案 正如其他地方已经说过的那样,可怕的事实是,您必须进行丑陋的修改才能允许从同级模块中导入数据或从该__main__模块中的父级程序包中进行导入。PEP 366中详细介绍了该问题。PEP 3122试图以一种更合理的方式处理进口货,但圭多拒绝了它的原因
__main__
唯一的用例似乎是正在运行的脚本,它们恰好位于模块目录中,我一直将其视为反模式。
(这里)
不过,我会定期使用这种模式
# Ugly hack to allow absolute import from the root folder # whatever its name is. Please forgive the heresy. if __name__ == "__main__" and __package__ is None: from sys import path from os.path import dirname as dir path.append(dir(path[0])) __package__ = "examples" import api
这path[0]是您正在运行的脚本的父文件夹和dir(path[0])顶级文件夹。
虽然我仍然不能使用相对导入,但是它确实允许从顶层(在您的示例api的父文件夹中)进行绝对导入。