Flask中的装饰器Decorator和上下文管理器ContextManager

发布于:2025-03-18 ⋅ 阅读:(17) ⋅ 点赞:(0)

Flask 中的 装饰器(Decorator)上下文管理器(Context Manager) 都用于增强代码的功能,但它们的用途和实现方式不同。


1. 装饰器(Decorator)

特点

用于修改或增强函数/类的行为,不影响原始代码。
常用于 Flask 的路由、请求前后处理、认证等
基于 Python 的高阶函数,使用 @ 语法。

示例

from flask import Flask

app = Flask(__name__)

# Flask 路由装饰器
@app.route('/')
def home():
    return "Hello, Flask!"

这里 @app.route('/') 是一个装饰器,它修改了 home() 的行为,使其成为 Flask 的路由处理函数

应用场景

  • 定义 URL 路由@app.route)。
  • 请求前后钩子@app.before_request@app.after_request)。
  • 自定义权限认证@login_required)。
  • 错误处理@app.errorhandler(404))。

自定义 Flask 装饰器

from flask import request, jsonify

def login_required(f):
    def wrapper(*args, **kwargs):
        token = request.headers.get("Authorization")
        if not token:
            return jsonify({"error": "未授权"}), 401
        return f(*args, **kwargs)
    return wrapper

@app.route('/protected')
@login_required
def protected():
    return jsonify({"message": "成功访问受保护资源"})

这里 @login_required 在执行视图函数前先检查是否有 Authorization,如果没有则返回 401


2. 上下文管理器(Context Manager)

特点

用于管理资源的生命周期(初始化 & 释放),比如数据库连接、文件操作。
通常与 with 语句一起使用,确保资源在使用后自动释放。
可以使用 @contextmanager(简化)或 class(完整实现)。

示例

from contextlib import contextmanager

@contextmanager
def my_resource():
    print("资源初始化")
    yield "资源对象"
    print("资源清理")

with my_resource() as res:
    print(f"正在使用: {res}")

输出:

资源初始化
正在使用: 资源对象
资源清理

应用场景

  • 数据库会话管理
  • 文件操作
  • Flask 的应用上下文和请求上下文
  • 事务处理(commit/rollback

Flask 中的数据库上下文管理

from contextlib import contextmanager
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine

engine = create_engine("sqlite:///example.db")
Session = sessionmaker(bind=engine)

@contextmanager
def get_db_session():
    """管理数据库连接"""
    session = Session()
    try:
        yield session  # 提供 session
        session.commit()  # 事务提交
    except Exception:
        session.rollback()  # 事务回滚
        raise
    finally:
        session.close()  # 关闭连接

@app.route('/data')
def get_data():
    with get_db_session() as session:
        result = session.execute("SELECT 'Hello Flask!'").fetchone()
        return result[0]
  • yield session 提供数据库连接
  • commit() 提交事务
  • rollback() 出错时回滚
  • close() 关闭连接,避免资源泄露

3. Flask 装饰器 vs. 上下文管理器

特性 装饰器(Decorator) 上下文管理器(Context Manager)
作用 修改/增强函数行为 管理资源的创建和释放
使用方式 @ 语法修饰函数 with 语句
常见用途 Flask 路由、请求前后钩子、认证 数据库连接、文件操作、事务管理
是否修改原函数
何时执行 函数调用前后 进入/退出 with 代码块时

4. 结合使用装饰器 & 上下文管理器

装饰器和上下文管理器可以结合使用,例如,在 Flask 中使用装饰器封装数据库事务

def transactional(f):
    """装饰器封装事务"""
    @wraps(f)
    def wrapper(*args, **kwargs):
        with get_db_session() as session:
            return f(session, *args, **kwargs)
    return wrapper

@app.route('/users')
@transactional
def get_users(session):
    """获取用户列表"""
    return {"users": session.execute("SELECT * FROM users").fetchall()}

transactional 作为装饰器
get_db_session() 作为上下文管理器
自动管理数据库事务


5. 结论

  1. 装饰器
    • 修改函数的行为,增强功能(如 Flask 路由、认证)。
    • @ 语法修饰函数,在函数调用时执行。
    • 适用于权限验证、错误处理、日志等场景
  2. 上下文管理器
    • 管理资源的生命周期(如数据库连接、文件操作)。
    • with 语句管理资源,确保正确释放。
    • 适用于事务、应用上下文、请求上下文等
  3. 两者可以结合,如用装饰器封装数据库事务,让代码更简洁优雅。

如果你的 Flask 项目中涉及资源管理(数据库、文件),建议结合使用两者,让代码更高效! 🚀


网站公告

今日签到

点亮在社区的每一天
去签到