У меня есть проект, который я хочу структурировать так:

myproject
  __init__.py
  api
    __init__.py
    api.py
  backend
    __init__.py
    backend.py
  models
    __init__.py
    some_model.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.

Что я здесь не так делаю? Как я могу импортировать файл из другого каталога, который не является подкаталогом?

42
Gasp0de 1 Мар 2018 в 01:09

4 ответа

Лучший ответ

Во-первых, это утверждение импорта:

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 .
5
sodimel 18 Ноя 2019 в 08:54

Ответ здесь: Импорт файлов из другой папки несколькими сложными способами. Вы также можете использовать:

Импорт ОС

Os.chdir ( ' Ваш / Новый / Каталог " )

Импортировать что угодно

Который очень не элегантен, но делает работу. Не забудьте перейти обратно, если вам нужно больше из предыдущего каталога.

Аллен

-2
Allen Windhorn 28 Фев 2018 в 22:43

К сожалению, Python найдет ваш файл, только если он находится в системном пути. Но не бойся! Есть способ обойти это!

Используя модуль sys в python, мы можем добавить каталог к пути только во время работы Python, и как только Python перестанет работать, он удалит его из пути.

Вы можете сделать это:

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

Однако важно импортировать sys и указать путь к каталогу, прежде чем импортировать файл.

Удачи!

Иордания .

0
Jordan Mattiuzzo 28 Фев 2018 в 22:18

Хотя все приведенные выше ответы верны, я нашел еще один ответ, который хочу добавить для полноты изложения. Очевидно, каталог, в котором находится первоначально выполненный скрипт, и его подкаталоги автоматически добавляются в список путей.

Это означает, что если вы создадите стартовый скрипт (например, main.py) для корневого каталога ваших проектов, который позже выполнит все остальные модули (api.py и backend.py в моем случае), то приведенный выше метод с использованием

from models import some_model

Буду работать.

-1
Gasp0de 28 Фев 2018 в 22:32