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. 修饰符的本质:函数当参数,返回新函数 🧠
关键字:高阶函数、包装函数、闭包
内容详解:
修饰符的核心是 高阶函数(把函数当参数,返回新函数),流程是:
- 定义修饰符函数(比如
my_decorator),接收原函数func当参数; - 在修饰符里定义
wrapper(包装函数),写“新增功能 + 调用原函数”; - 修饰符返回
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)”的体现——在不修改核心代码的前提下,给函数“切面式”地增加功能!
正文完