Тестирующая колба - как избежать кругового импорта

Некоторое время я использовал Django, но решил попробовать Flask для моего последнего стороннего проекта. Поскольку я не хотел, чтобы все мое приложение было в одном файле, я следовал приведенной здесь документации, чтобы превратить мое приложение Flask в пакет. Важно, что эти инструкции вводят своего рода циклический импорт:

Каждый программист на Python ненавидит их, но мы только что добавили: циклический импорт (вот когда два модуля зависят друг от друга. В этом случае views.py зависит от __init__.py). Имейте в виду, что это плохая идея в целом, но здесь это на самом деле хорошо. Причина этого в том, что мы на самом деле не используем представления в __init__.py, а просто следим за тем, чтобы модуль был импортирован, и мы делаем это в нижней части файла.

Действительно, это еще не вызвало никаких проблем в моем приложении, и мое приложение не будет работать, если я удалю эту строку. Однако мой побочный проект стал достаточно большим, и я решил попробовать написать для него модульные тесты, используя Flask-Testing. Во всей своей документации они просто from package import app как обычно, как в каждом подмодуле в моем приложении. Однако, если я уроню tests.py в главном каталоге пакета и попробуйте этот импорт, затем попробуйте запустить тесты, он завершится неудачно с циклическим импортом, упомянутым выше:

File "/home/me/my_app/my_app/__init__.py", line 165, in <module>
  import views
File "/home/me/my_app/my_app/views.py", line 23, in <module>
  from my_app import app, db
ImportError: cannot import name app

В документации для Flask-Testing, а также в других местах, таких как раздел Mega-Tutorial по модульному тестированию, этот импорт выполнен и, похоже, "просто работает". Для меня, однако, это единственный раз, когда у меня возникла проблема с этим циклическим импортом. Что я пропустил?

1 ответ

Как задокументировано здесь ваш my_app/__init__.py должно выглядеть так:

from flask import Flask

app = Flask(__name__)
from my_app import views

Обратите внимание, что app определяется перед импортом views из вашей посылки. Если вы следуете этому правилу, у вас не будет проблем с циклическим импортом.

Другие вопросы по тегам