什么是Python装饰器
如果你写过Python超过一周,你一定见过函数上方那个@符号。这就是装饰器——一个强大且易用的编程工具。
Python装饰器允许你将一个函数"包裹"在另一个函数中。它们可以在不修改原函数代码的情况下,改变或扩展函数的行为。装饰器被广泛应用于Flask、Django、FastAPI、pytest,甚至Python标准库中。
装饰器的工作原理
装饰器基础
装饰器本质上是一个函数,它接收另一个函数作为参数,并返回一个新的函数或修改后的原函数。
def decorator(func):
def wrapper():
print("调用前")
func()
print("调用后")
return wrapper
@decorator
def say_hello():
print("你好!")
say_hello()
执行结果:
调用前
你好!
调用后
@decorator 实际上是以下写法的语法糖:
say_hello = decorator(say_hello)
装饰器的内部机制
要理解Python装饰器,需要掌握几个关键概念:
- 在Python中,函数是一等公民(first-class objects)
- 函数可以作为参数传递给其他函数
- 函数内部可以定义其他函数
- 闭包(closure)机制的存在
通用装饰器模板
最简装饰器模板如下:
def decorator(func):
def wrapper(*args, **kwargs):
# 函数执行前的操作
result = func(*args, **kwargs)
# 函数执行后的操作
return result
return wrapper
装饰器实战案例
计时装饰器
import time
def timing(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
execution_time = time.time() - start
print(f"{func.__name__} 执行耗时 {execution_time:.4f} 秒")
return result
return wrapper
@timing
def slow_func():
time.sleep(1)
return "操作完成"
slow_func()
这个装饰器非常适合用于函数性能分析和代码优化。
权限验证装饰器
def require_admin(func):
def wrapper(user, *args, **kwargs):
if user != "admin":
raise PermissionError("访问被拒绝")
return func(user, *args, **kwargs)
return wrapper
@require_admin
def delete_database(user):
print("数据库已删除!")
return True
delete_database("admin") # 成功执行
这种装饰器通过控制对关键函数的访问,有效保障了应用安全。
日志记录装饰器
import logging
from functools import wraps
def log_calls(func):
@wraps(func)
def wrapper(*args, **kwargs):
logging.info(f"调用函数 {func.__name__},参数为 {args}, {kwargs}")
try:
result = func(*args, **kwargs)
logging.info(f"函数 {func.__name__} 执行成功")
return result
except Exception as e:
logging.error(f"函数 {func.__name__} 出错:{e}")
raise
return wrapper
带参数的装饰器
创建装饰器工厂
当装饰器需要接收参数时,需要创建一个装饰器工厂:
def repeat(n):
def decorator(func):
def wrapper(*args, **kwargs):
results = []