Импорт модулей Python из разных каталогов - PullRequest
0 голосов
/ 31 октября 2019

У меня есть приложение для колб со следующей структурой:

app/
  __init__.py
  myapp.py
  common/
    tool1.py
    tool2.py
  web/
    __init__.py
    views.py
    api/
      api_impl.py
  worker/
    __init__.py
    worker.py
    tasks.py

Я инициализирую в myapp.py важный объект, который я использую в нескольких местах, и я могу получить к нему доступ из common/tool1.py и web/api/api_impl.pyс from myapp import object. Я смог использовать tool1 и tool2 в нескольких местах в web/ и myapp.py при импорте с from common.tool1 import tool1_def.

Другие важные факты в myapp.py есть import web оператор для чертежей и app/__init__.py и worker/__init__.py пусты. web/__init__.py содержит определения чертежей для маршрутов.

Я могу без проблем запустить приложение с gunicorn, но когда я пытаюсь запустить моего работника с python app/worker/worker.py, я получаю ошибку ModuleNotFoundError: No module named 'myapp'. worker.py пытается импортировать тот же объект, определенный в myapp.py.

Я просто не понимаю, почему я могу запустить приложение, и оно работает, но когда я пытаюсь запустить работника, это не так! Я определенно не до конца понимаю систему импорта в этом случае, и все, что я прочитал онлайн, похоже, не совсем проясняет это.

Ответы [ 2 ]

1 голос
/ 31 октября 2019

Один метод, который мы регулярно используем для разработки и отладки (но также работает в производстве), заключается в следующем. Вы можете добавить это к каждому (оскорбляющему?) Модулю или ко всем модулям, если вы выберете.

import os
import sys

# Add your project root to sys.path.
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.realpath(__file__))))

from common import tool1
from common import tool2
from worker import worker
etc ...

Здесь вы добавляете корень проекта в sys.path. При выполнении импорта Python начинает с просмотра sys.path модуля, который вы пытаетесь импортировать. Итак, здесь вы добавляете корень проекта в качестве первого элемента в sys.path.

Еще одно преимущество - это то, что эти импорты явны для вашего проекта. Например, если у вас есть локальный модуль workers, который вы хотите импортировать, но у вас также есть пакет workers в site-packages, это сначала будет выглядеть в вашем локальном проекте.

1 голос
/ 31 октября 2019

ваш рабочий импорт подразумевает, что корнем проекта является папка приложения. Таким образом, вам нужно отобрать вашего работника из этой папки (или добавить его в переменную окружения PYTHONPATH)

python worker/worker.py 

Или

python -m worker.worker

Кроме того, ваш __init__.py в папке приложения долженбыть удаленным, так как приложение - это не пакет, а корень проекта.

...