Что такое `flask.g` и как он используется в Flask?

«Что такое `flask.g` и как он используется в Flask?» — вопрос из категории Библиотеки и модули, который задают на 10% собеседований Python Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

flask.g — это специальный объект в Flask, предназначенный для хранения данных, специфичных для текущего запроса. Он доступен на протяжении всего жизненного цикла обработки одного HTTP-запроса и позволяет передавать данные между различными функциями, хуками (before_request, after_request) и представлениями без использования глобальных переменных или передачи их через параметры.

Назначение: Основное назначение flask.g — предоставление временного хранилища для данных, которые должны быть доступны в разных частях приложения в рамках одного запроса, но не должны сохраняться между запросами. Это помогает избежать использования глобальных переменных, которые могут привести к проблемам с потокобезопасностью и состоянием.

Пример использования:

from flask import Flask, g, request, jsonify

app = Flask(__name__)

# Предположим, у нас есть простая модель пользователя
class User:
    def __init__(self, name):
        self.name = name

def get_user_from_request(req):
    # В реальном приложении здесь была бы логика аутентификации
    # и получения пользователя из БД или сессии
    user_id = req.args.get('user_id')
    if user_id == '1':
        return User("Alice")
    return User("Guest")

@app.before_request
def before_request_hook():
    """
    Этот хук выполняется перед каждым запросом.
    Здесь мы можем загрузить пользователя и сохранить его в g.
    """
    g.user = get_user_from_request(request)
    print(f"User for this request: {g.user.name}")

@app.route('/')
def index():
    """
    В представлении мы можем легко получить доступ к g.user.
    """
    return f"Hello, {g.user.name}!"

@app.route('/profile')
def profile():
    return jsonify({"username": g.user.name, "message": "Welcome to your profile!"})

# Для запуска:
# if __name__ == '__main__':
#     app.run(debug=True)

Ключевые особенности и рекомендации:

  • Жизненный цикл: Данные, хранящиеся в g, существуют только в течение одного запроса. После завершения запроса объект g и его содержимое очищаются.
  • Потокобезопасность: flask.g является потокобезопасным, так как каждый поток (обрабатывающий отдельный запрос) имеет свою собственную копию g.
  • Не для постоянного хранения: g не предназначен для хранения данных между запросами (для этого используются сессии, базы данных или кэш).
  • Избегайте соединений с БД: Хотя технически можно хранить соединения с базой данных в g, для этого существуют более специализированные расширения Flask (например, Flask-SQLAlchemy), которые лучше управляют жизненным циклом соединений.
  • Удобство: Упрощает передачу контекстных данных (например, текущего пользователя, соединения с БД, конфигурации) между различными слоями приложения в рамках одного запроса.