Как поделиться глобальным объектом приложения в колбе?
Я использую колбу и пытаюсь сделать следующее.
Я определил файл main.py, через который я хочу запустить мое приложение, то есть python main.py -
from flask import Flask
from view import tags
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run()
Я определил пакет с именем view, в котором я буду объявлять разные модули просмотра, каждый из которых имеет свои собственные маршруты. view.tags.py -
from flask import Flask
app = Flask(__name__)
@app.route('/e')
def hello_world2():
return 'Hello World!'
Поэтому мне нужно иметь глобальный объект приложения в моей main.py для запуска сервера, а также в классах представления моего пакета для регистрации маршрутов. Итак, как мне создать глобальный объект приложения и поделиться им между всеми классами?
Спасибо,
Муртаза
Ответы
Ответ 1
Один из способов - создать общий пакет и добавить файл __init__.py
под тем, где вы объявляете все глобальные переменные. Например, в вашем случае вы можете создать что-то вроде:
myapplication/
* __init__.py
* myviews/
* __init__.py
* view.py
* tags.py
и т.д.
Теперь вы добавляете следующий код в файл __init__.py
:
app = Flask(__name__)
Теперь вы можете использовать эту переменную приложения в любом месте, пока вы импортируете приложение mypplication.
import myapplication.myviews.view
Ответ 2
Вы можете импортировать current_app из фляжки. В нем хранится ссылка на объект глобального приложения.
from flask import current_app as app
def home():
return render_template('base.html', name=app.name)
Ответ 3
Во-первых, я бы посоветовал взглянуть на Blueprints http://flask.pocoo.org/docs/blueprints/ Это поможет легко организовать приложение.
Также взгляните на http://flask.pocoo.org/docs/api/#flask.current_app flask.current_app способ получения экземпляра приложения в других модулях.
Эта ссылка также может быть полезна для организации и создания колб-приложения (оно точно не идеально, но может дать вам некоторые идеи) - Large-app-how-to.md
Повеселись :)
Ответ 4
Просто импортируйте его из других файлов. Возможно, лучший способ сделать это - разместить объект приложения в одном файле и импортировать из него все остальное.
Например, у вашего main.py все равно может быть:
from flask import Flask
from view import tags
app = Flask(__name__)
И затем в других файлах вы можете сделать:
from .main import app
или, если вне вашего пакета, просто используйте полную строку
from mypackagename.main import app
Одна вещь, которая должна быть осторожна - это круговой импорт. Самый простой способ справиться с этой проблемой - сначала создать свое приложение, а затем импортировать все, что вам нужно, из вашего базового файла после его создания.
Итак, например:
from flask import Flask
app = Flask(__name__)
# do some stuff with app
from .views import view1, view2
from .server import run
Пока вы добавляете импорт после создания приложения, как указано выше, у вас не должно быть проблем с циклическим импортом.
Ответ 5
Что касается импорта и использования current_app из флэка в функции "helper" python в отдельном исходном файле, это работает до тех пор, пока контекст текущего приложения уже настроен (например, полученный веб-запрос). У меня есть случай, когда во время инициализации приложения (app.run еще не вызывается), app.logger вызывается в вспомогательной функции.
Прежде чем я его исправил (см. ниже), я получил трассировку стека, отмеченную "RuntimeError: Работа вне контекста приложения".
Пример решения:
main.py:
import helper
...
app = Flask(__name__.split('.')[0],
template_folder="templates",
static_folder="static")
...
# Fix: Create an app context
with app.app_context():
helper.dbopen(...)
...
app.run(...)
helper.py:
from flask import current_app as app
...
def dbopen():
app.logger.info(...)
...
Ответ 6
Если у вас есть файл AppName.py
, в котором вы определяете app
, а затем у вас есть другой файл Foobar.py
, который ему нужен, вы всегда можете сказать в AppName.py
:
import Foobar
Foobar.app = app
Затем в Foobar.py
вы сможете использовать приложение в своих функциях. Одна вещь, которую вы хотите быть осторожной, заключается в том, что вы не можете иметь код в Foobar.py
, который запускается сразу же после вызова файла, зависит от переменной app
, которая передается после импорта.