Python装饰器是一种非常实用的语法特性,它允许我们在不修改原有函数代码的情况下,为函数添加新的功能。在实际的后端开发场景中,权限校验和日志记录是非常常见的需求,通过装饰器可以高效地实现这些功能的统一增强。

装饰器基础原理
装饰器本质上是一个接收函数作为参数,并返回一个新函数的高阶函数。我们可以把额外的逻辑放在装饰器内部,在调用原函数前后执行这些逻辑,从而实现功能增强。基础的装饰器结构如下:
# 基础装饰器示例
def my_decorator(func):
def wrapper(*args, **kwargs):
# 原函数执行前的逻辑
print("执行前处理逻辑")
result = func(*args, **kwargs)
# 原函数执行后的逻辑
print("执行后处理逻辑")
return result
return wrapper
# 使用装饰器
@my_decorator
def test_func():
print("原函数执行")
test_func()
权限校验装饰器实现
在接口开发中,我们常常需要校验当前用户是否有权限调用某个接口,比如只有管理员角色可以调用删除用户的接口。我们可以编写一个权限校验装饰器,在接口函数执行前校验用户权限。
# 模拟用户权限数据
user_permissions = {
"user1": ["read", "write"],
"admin": ["read", "write", "delete"]
}
# 权限校验装饰器
def check_permission(required_permission):
def decorator(func):
def wrapper(*args, **kwargs):
# 从参数中获取当前用户名,实际场景中可能从请求头获取token解析得到
current_user = kwargs.get("current_user")
if not current_user:
raise ValueError("未获取到用户信息")
# 校验用户是否有对应权限
if required_permission not in user_permissions.get(current_user, []):
raise PermissionError(f"用户{current_user}没有{required_permission}权限")
# 有权限则执行原函数
return func(*args, **kwargs)
return wrapper
return decorator
# 使用权限装饰器的接口函数
@check_permission("delete")
def delete_user(target_user, current_user=None):
print(f"删除用户{target_user}成功")
return True
# 测试调用
try:
delete_user("user2", current_user="user1")
except PermissionError as e:
print(e)
try:
delete_user("user2", current_user="admin")
except PermissionError as e:
print(e)
日志记录装饰器实现
日志记录可以帮我们追踪函数的调用情况,比如记录函数的入参、出参、执行时间等信息,方便后续的问题排查。我们可以编写一个通用的日志记录装饰器。
import time
# 日志记录装饰器
def log_record(func):
def wrapper(*args, **kwargs):
start_time = time.time()
print(f"函数{func.__name__}开始执行,入参:args={args}, kwargs={kwargs}")
try:
result = func(*args, **kwargs)
end_time = time.time()
print(f"函数{func.__name__}执行完成,出参:{result},耗时:{end_time - start_time:.4f}秒")
return result
except Exception as e:
end_time = time.time()
print(f"函数{func.__name__}执行异常,异常信息:{e},耗时:{end_time - start_time:.4f}秒")
raise
return wrapper
# 使用日志装饰器的函数
@log_record
def add_user(user_name, age):
time.sleep(0.1) # 模拟耗时操作
print(f"添加用户{user_name}成功")
return {"name": user_name, "age": age}
# 测试调用
add_user("张三", 25)
组合使用权限与日志装饰器
装饰器可以叠加使用,我们可以同时给一个函数添加权限校验和日志记录的功能,只需要在函数上方依次添加两个装饰器即可。
# 组合使用两个装饰器
@log_record
@check_permission("write")
def update_user(user_id, new_info, current_user=None):
time.sleep(0.05)
print(f"更新用户{user_id}的信息为{new_info}")
return True
# 测试调用
try:
update_user(1, {"age": 30}, current_user="user1")
except PermissionError as e:
print(e)
try:
update_user(1, {"age": 30}, current_user="admin")
except PermissionError as e:
print(e)
通过上面的案例可以看出,使用装饰器实现权限校验和日志记录的功能增强,避免了在每个业务函数中重复编写相同的逻辑,大幅提升了代码的复用性和可维护性。如果后续需要修改权限校验逻辑或者日志记录格式,只需要修改对应的装饰器即可,不需要逐个修改业务函数。