函数修饰符——包装函数:给函数“穿外套”的黑科技 🧥

215次阅读

1. 函数修饰符:不用改代码,给函数“加 buff”🎮

关键字:函数修饰符、@语法、包装函数内容详解:
函数修饰符(也叫“装饰器”)是 Python 的“黑科技”——不用修改函数的代码,就能给它 新增功能(比如计时、日志、权限校验)。
类比:函数是“一件 T 恤”,修饰符是“外套”——穿上外套(加修饰符),T 恤本身没变,但多了“保暖 / 防晒”的功能!
写法是用 @修饰符名 放在函数定义上面,比如:

# 定义修饰符(外套)def my_decorator(func):
    # 定义包装函数(外套的功能)def wrapper():
        print("外套:函数执行前的准备工作~")
        func()  # 调用原函数(T 恤)print("外套:函数执行后的收尾工作~")
    return wrapper

# 给函数穿外套
@my_decorator
def say_hello():
    print("T 恤:Hello World!")

# 调用函数
say_hello()

运行结果:

外套:函数执行前的准备工作~
T 恤:Hello World!外套:函数执行后的收尾工作~

原函数 say_hello 的代码没改,但多了“前后打印”的功能——这就是修饰符的魔力!

2. 修饰符的本质:函数当参数,返回新函数 🧠

关键字:高阶函数、包装函数、闭包

内容详解:
修饰符的核心是 高阶函数(把函数当参数,返回新函数),流程是:

  1. 定义修饰符函数(比如 my_decorator),接收原函数func 当参数;
  2. 在修饰符里定义wrapper(包装函数),写“新增功能 + 调用原函数”;
  3. 修饰符返回wrapper——所以被修饰的函数,实际执行的是wrapper

前面的 @my_decorator 等价于:say_hello = my_decorator(say_hello)——把原函数“替换”成包装后的新函数!

3. 实用修饰符:给函数加“执行时间统计”⏱️

关键字:计时修饰符、通用功能

内容详解:
写一个修饰符,统计任意函数的执行时间——不用给每个函数写计时代码:

import time

# 定义计时修饰符
def time_it(func):
    def wrapper(*args, **kwargs):  # *args 和 **kwargs 接收任意参数
        start = time.time()  # 开始时间
        result = func(*args, **kwargs)  # 调用原函数,传参数
        end = time.time()  # 结束时间
        print(f"函数 {func.__name__} 执行时间:{end - start:.4f}秒")
        return result  # 返回原函数的结果
    return wrapper

# 给计算函数穿“计时外套”@time_it
def calculate_sum(n):
    total = 0
    for i in range(n):
        total += i
    return total

# 调用函数,自动计时
sum_result = calculate_sum(1000000)
print("计算结果:", sum_result)

运行后会输出:函数 calculate_sum 执行时间:0.0456 秒 ——这个修饰符可以给 任意函数 用,复用性拉满!

4. Web 场景:用修饰符做“登录权限校验”🕸️

关键字:Flask 修饰符、权限校验

内容详解:
在 Flask Web 应用中,用修饰符限制“未登录用户不能访问某些页面”——不用在每个视图函数里写校验:

from flask import Flask, session, redirect, url_for

app = Flask(__name__)
app.secret_key = "your_secret_key"  # 会话加密密钥

# 定义“登录校验”修饰符
def login_required(func):
    def wrapper(*args, **kwargs):
        # 检查 session 里是否有 user_id(代表已登录)if "user_id" not in session:
            return redirect(url_for("login"))  # 未登录则跳转到登录页
        return func(*args, **kwargs)  # 已登录则执行原函数
    return wrapper

# 登录页:不用校验
@app.route("/login")
def login():
    session["user_id"] = 1  # 模拟登录,写入 session
    return "登录成功!"

# 个人中心:需要登录校验(加修饰符)@app.route("/profile")
@login_required
def profile():
    return "个人中心页面(已登录才能看)"

if __name__ == "__main__":
    app.run(debug=True)

现在访问/profile

  • 未登录时,自动跳转到/login
  • 登录后,才能看到个人中心——修饰符把“权限校验”逻辑统一封装,视图函数更简洁!

5. 高阶玩法:带参数的修饰符——更灵活的“外套”🎨

关键字:带参修饰符、三层函数

内容详解:
有时候需要给修饰符传参数(比如“日志修饰符”要指定日志级别),这时候要写 三层函数

def log_with_level(level):
    # 第一层:接收修饰符的参数
    def decorator(func):
        # 第二层:接收原函数
        def wrapper(*args, **kwargs):
            # 第三层:包装逻辑(用 level 参数)print(f"[{level}] 函数 {func.__name__} 开始执行")
            result = func(*args, **kwargs)
            print(f"[{level}] 函数 {func.__name__} 执行结束")
            return result
        return wrapper
    return decorator

# 给函数加“INFO 级别日志”的修饰符
@log_with_level(level="INFO")
def add(a, b):
    return a + b

# 调用函数
print(add(2, 3))

运行结果:

[INFO] 函数 add 开始执行
[INFO] 函数 add 执行结束
5

带参修饰符让“外套”能定制功能(比如换日志级别),灵活性更高!

6. 划重点:修饰符的核心优势 🚀

关键字:代码复用、逻辑解耦、简洁性

内容详解:
修饰符之所以强大,是因为它解决了“重复逻辑分散”的问题:

  • 📦 代码复用:把“计时、日志、权限校验”等通用逻辑写成修饰符,任意函数都能复用;
  • 🔌 逻辑解耦:业务逻辑(比如计算、页面渲染)和通用逻辑(比如计时)分开,代码更清晰;
  • 📝 代码简洁 :不用给每个函数写重复代码,加个@修饰符 就搞定。

这也是 Python 中“面向切面编程(AOP)”的体现——在不修改核心代码的前提下,给函数“切面式”地增加功能!

正文完
 0