首页 > 解决方案 > 从本地脚本导入本地包

问题描述

我有这个项目结构:

.
├── README.md
├── my_project
│   ├── __init__.py
│   ├── config.py
│   ├── integrations
│   │   ├── __init__.py
│   │   └── google_places.py
├── requirements.txt
└── scripts
    └── my_script.py

my_script.py我有:

from my_project.integrations.google_places import GooglePlaces

但是,运行时出现以下错误python scripts/my_script.py

ModuleNotFoundError: No module named 'my_project'

在本地我可以pip install -e .我的包(通过添加一个setup.py混合),但是因为我需要从 GitHub Actions 运行它,所以感觉追求相同的途径是没有意义的。

我一直在阅读有关 manipulating的文章sys.path,但它似乎有点骇人听闻。

由于这是一个相当常见的设置(我猜),修复上述错误的推荐方法是什么?如果有意义,我可以更改项目结构。

标签: python

解决方案


这也让我感到惊讶,但是在阅读了这个非常全面的答案https://stackoverflow.com/a/54613085/6180150,并进入了关于 python 中模块搜索路径的链接 python 文档之后,我认为你必须调整PYTHONPATH. 问题是这两个python文件位于两个单独的包中,即scriptsmy_project,所以my_script.py找不到google_places.py,因为PYTHONPATH只包含当前包而不是父文件夹,python只会搜索以下目录(参见前面的搜索路径文档):

  • 包含输入脚本的目录(或未指定文件时的当前目录)。
  • PYTHONPATH(目录名称列表,与 shell 变量 PATH 具有相同的语法)。
  • 安装相关的默认值。

同样在此评论中:Python: 'ModuleNotFoundError' when trying to import module from imported package上述答案的回复者很好地解释了调整PYTHONPATH并不是一个真正的解决方案(虽然我也会这么觉得),但是根据记录的解决方案蟒蛇也是。

如果可能的话,如果我在你的鞋子里,我想我会把它搬进my_script.py包裹my_project里,如下所示。

.
├── README.md
├── my_project
│   ├── __init__.py
│   ├── config.py
│   ├── integrations
│   │   ├── __init__.py
│   │   └── google_places.py
│   └── my_script.py
└── requirements.txt

然后,您可以将导入调整为:

from integrations.google_places import GooglePlaces

编辑:

如果您喜欢使用以下文件树结构(甚至原始文件应该可以)。

.
├── README.md
├── my_project
│   ├── __init__.py
│   ├── config.py
│   ├── integrations
│   │   ├── __init__.py
│   │   └── google_places.py
│   └── scripts
│       └── my_script.py
└── requirements.txt

您可以像这样修改 sys.path ,然后使用原始导入语句:

import sys
import os

sys.path.insert(0, os.getcwd())
from my_project.integrations.google_places import GooglePlaces

推荐阅读