Вопрос или проблема
Я думаю, что у меня есть круговой импорт между main.py и init.py при инициализации приложения, но я не могу понять, как правильно это настроить.
Буду признателен за любую помощь. Я включил несколько изображений о проекте.
Ошибка: При импорте 'main' возникло исключение ImportError:
Трассировка (последний вызов последним): Файл "/Users/x/Sites/learning/python/flask/venv/lib/python3.9/site-packages/flask/cli.py", строка 218, в locate_app
__import__(module_name)
Файл "/Users/x/Sites/learning/python/flask/main.py", строка 1, в <module> из application import app Файл "/Users/x/Sites/learning/python/flask/application/__init__.py", строка 4, в <module>
из application import routes
Файл "/Users/x/Sites/learning/python/flask/application/routes.py", строка 1, в <module>
из application import app, db
ImportError: невозможно импортировать имя 'app' из частично инициализированного модуля 'application' **(вероятно, из-за кругового импорта)** (/Users/x/Sites/learning/python/flask/application/__init__.py)
Вот несколько скриншотов проекта:
Установленные пакеты:
main.py
из application import app
init.py
из flask import Flask
из config import Config
из flask_mongoengine import MongoEngine
из application import routes
db = MongoEngine()
app = Flask(__name__)
app.config.from_object(Config)
db.init_app(app)
routes.py
из application import app, db
из flask import render_template, request, Response, json
courseData = [
{"courseID": "1111", "title": "PHP 111", "description": "Введение в PHP", "credits": "3", "term": "Осень, Весна"},
{"courseID": "2222", "title": "Java 1", "description": "Введение в программирование на Java", "credits": "4","term": "Весна"},
{"courseID": "3333", "title": "Adv PHP 201", "description": "Продвинутая программирование на PHP", "credits": "3", "term": "Осень"},
{"courseID": "4444", "title": "Angular 1", "description": "Введение в Angular", "credits": "3","term": "Осень, Весна"},
{"courseID": "5555", "title": "Java 2", "description": "Продвинутая программирование на Java", "credits": "4","term": "Осень"}]
@app.route("/")
@app.route("/index")
def index():
return render_template("index.html", index=True)
@app.route("/login")
def login():
return render_template("login.html", login=True)
@app.route("/enrollment", methods=["GET","POST"])
def enrollment():
id = request.form.get('courseID')
title = request.form['title']
term = request.form.get('term')
return render_template("enrollment.html", enrollment=True, data={"id":id,"title":title,"term":term})
@app.route("/courses")
@app.route("/courses/<term>")
def courses(term="2024"):
return render_template("courses.html", courseData=courseData, courses=True, term=term)
@app.route("/register")
def register():
return render_template("register.html", register=True)
@app.route("/api/")
@app.route("/api/<idx>")
def api(idx=None):
if idx is None:
jdata = courseData
else:
jdata = courseData[int(idx)]
return Response(json.dumps(jdata), mimetype="application/json")
class User(db.Document):
user_id = db.IntField(unique=True)
first_name = db.StringField(max_length=50)
last_name = db.StringField(max_length=50)
email = db.StringField(max_length=30)
password = db.StringField(max_length=30)
@app.route("/user")
def user():
User(user_id=1, first_name="x", last_name="x", email="[email protected]", password="pass").save()
User(user_id=2, first_name="Sam", last_name="x", email="[email protected]", password="pass").save()
users = User.objects.all()
return render_template("user.html", users=users)
Что конкретно вы сделали в routes? Проблема, вероятно, в этом.
Ответ или решение
Ошибка ImportError: cannot import name 'app' from partially initialized module 'application' (most likely due to a circular import)
указывает на наличие проблемы с "циклическим импортом" в вашем коде на Python. Эта проблема часто возникает в проектах, когда два или более модуля пытаются импортировать друг друга, что создает цикл, в результате которого Python не может правильно инициализировать модули. Давайте рассмотрим, как это происходит в вашем случае, и как вы можете это исправить.
Анализ структуры проекта
Исходя из вашего описания и приведенного кода, вы имеете три основных файла в проекте:
- main.py
- application/init.py
- application/routes.py
В файле main.py
вы импортируете app
из модуля application
, а в файле application/__init__.py
вы также имплементируете routes
, который в свою очередь пытается импортировать app
снова. Это создает циклическую зависимость.
Подробный разбор
-
Основной модуль
main.py
:from application import app
-
Инициализация приложения в
application/__init__.py
:from flask import Flask from config import Config from application import routes db = MongoEngine() app = Flask(__name__) app.config.from_object(Config) db.init_app(app)
-
Файл маршрутов
application/routes.py
:from application import app, db
Способы решения
Чтобы устранить циклический импорт, вы можете следовать нескольким шагам:
1. Измените порядок импорта
Попробуйте изменить порядок импорта в файле application/routes.py
. Например, перенесите импорт app
в функции, где он вам нужен, а не на уровне модуля:
# application/routes.py
from application import db
from flask import render_template, request, Response, json
def get_app():
from application import app
return app
@app.route("/")
@app.route("/index")
def index():
app = get_app()
return render_template("index.html", index=True)
# Остальные маршруты...
2. Используйте lazy loading (отложенный импорт)
Если переставить импорты не помогает, вы можете использовать так называемый lazy loading
, делая импорт внутри функций или методов, что позволяет избежать циклического импорта.
3. Пересмотрите структуру проекта
Если проблема остается нерешенной, возможно, стоит пересмотреть архитектуру вашего приложения. Например, в рамках Flask вы можете создать отдельные модули для маршрутов и базы данных, таким образом минимизируя необходимость циклических зависимостей.
4. Убедитесь в правильности настройки приложения
Также стоит удостовериться, что вы правильно организовали файлы конфигурации и подключения к БД, что улучшит читаемость и поддерживаемость кода.
Заключение
Ошибки циклического импорта могут быть одним из наиболее распространенных и сложных вопросов при разработке на Python, особенно для начинающих. Они требуют взвешенного подхода к организации кода и архитектуры проекта. Используя предложенные решения и корректируя порядок импортов, вы сможете устранить эту проблему и добиться правильной работы вашего приложения. Не забывайте также проводить тестирование после масштабных изменений, чтобы убедиться, что ваше приложение функционирует так, как задумано.