如何从Python中的其他文件夹导入模块?

Gas*_*0de 7 python python-3.x python-packaging

我有一个项目要结构如下:

myproject
  __init__.py
  api
    __init__.py
    api.py
  backend
    __init__.py
    backend.py
  models
    __init__.py
    some_model.py
Run Code Online (Sandbox Code Playgroud)

现在,我想同时在api.py和backend.py中导入some_model.py模块。如何正确执行此操作?我试过了

from models import some_model
Run Code Online (Sandbox Code Playgroud)

但是失败并显示为“ ModuleNotFoundError:没有名为'models'的模块”。我也试过

from ..models import some_model
Run Code Online (Sandbox Code Playgroud)

然后给我“ ValueError:尝试相对顶级包进行相对导入”。我在这里做错了什么?如何从其他目录(不是子目录)导入文件?

wim*_*wim 30

首先,这个导入语句:

from models import some_model
Run Code Online (Sandbox Code Playgroud)

应该命名空间:

# in myproject/backend/backend.py or myproject/api/api.py
from myproject.models import some_model
Run Code Online (Sandbox Code Playgroud)

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

export PYTHONPATH=/path/to/parent
Run Code Online (Sandbox Code Playgroud)

或者,您最好可以通过编写setup.py文件并安装您的软件包来完成。遵循PyPA打包指南。编写setup.py文件后,从同一目录中,执行此操作以在 中设置正确的条目sys.path

pip install --editable .
Run Code Online (Sandbox Code Playgroud)

  • 这是可行的,但你也应该能够从“myproject”包中进行相对导入,OP已经尝试过。什么会导致它不起作用? (2认同)
  • 在[第十亿次相对进口](/sf/ask/989295261/)中已经涵盖了十亿倍,所以我不会再讨论了。 (2认同)
  • 我创建了一个包并按照建议使用 pip install --editable 安装它。像魅力一样工作,谢谢! (2认同)

小智 21

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

使用python的sys模块,我们可以在Python运行的时候在路径中添加一个目录,一旦Python停止运行,它就会从路径中删除它。

您可以通过以下方式执行此操作:

import sys
sys.path.insert(0, '/path/to/application/app/folder')
import [file]
Run Code Online (Sandbox Code Playgroud)

但是,在导入文件之前导入 sys 并设置目录路径很重要。

祝你好运!

约旦。

  • 从代码内部更改路径虽然可能,但很麻烦而且很糟糕 - 它使测试设置更加困难并使导入顺序变得重要。 (8认同)