如何从不同的文件夹导入模块?

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

我有一个项目,我想这样构建:

myproject
├── api
│   ├── __init__.py
│   └── api.py
├── backend
│   ├── __init__.py
│   └── backend.py
├── models
│   ├── __init__.py
│   └── some_model.py
└── __init__.py

现在,我想在

some_model.py
api.py
中导入模块
backend.py
。我该如何正确地做到这一点?

我尝试过:

from models import some_model

但是失败了

ModuleNotFoundError: No module named 'models'

我也尝试过:

from ..models import some_model

这给了我

ValueError: attempted relative import beyond top-level package

我在这里做错了什么?如何从其他目录(不是子目录)导入文件?

python python-3.x python-import python-module python-packaging
3个回答
44
投票

首先,这个导入声明:

from models import some_model

应该命名空间:

# in myproject/backend/backend.py or myproject/api/api.py
from myproject.models import some_model

然后您需要将包含

myproject
的目录(我们称之为
/path/to/parent
)放入
sys.path
列表中。您可以通过设置环境变量来临时执行此操作:

export PYTHONPATH=/path/to/parent

或者,最好,您可以通过编写

setup.py
文件并安装包来完成。请遵循 PyPA 包装指南。编写完
setup.py
文件后,在同一目录中执行此命令以在
sys.path
中设置正确的条目:

pip install --editable .

31
投票

不幸的是,只有当您的文件位于系统路径中时,Python 才会找到您的文件。但不要害怕!有办法解决这个问题!

使用 python 的

sys
模块,我们可以在 Python 运行时向路径添加一个目录,仅用于程序的当前运行。这不会影响以后运行的任何其他 Python 程序。

您可以通过以下方式做到这一点:

import sys
import os
sys.path.insert(0, os.path.abspath('relative/path/to/application/folder'))
import [file]

在导入文件之前导入 sys 并设置目录路径非常重要。

如果您的库不靠近当前目录,绝对路径可能会更简单:

import sys
sys.path.insert(0, '/absolute/path/to/application/folder'))
import [file]

是的,这是一个黑客行为。但作为短期解决方法,它可能会有所帮助。


3
投票

我会提出两种方法:

通过绝对导入简单导入

some_model

from myproject.models import some_model

请注意,

myproject
应被视为一个模块(即具有
__init__.py


或者

您可以将之前的路径添加到我在此类并行级别模块中使用的

sys.path

import sys
sys.path.append('../')

from models import some_model
© www.soinside.com 2019 - 2024. All rights reserved.