2025-02-07 23:13阅读: 5评论: 0推荐: 0

python中的装饰器

Python中的装饰器(Decorator)

1. 什么是装饰器?

装饰器(Decorator)是 Python 中的一种高级函数功能,它允许在不修改原函数代码的情况下,动态地增强或修改函数的功能。常用于日志记录、权限验证、函数执行时间计算、缓存等场景。

装饰器本质上是一个高阶函数

  • 接受一个函数作为输入,并返回一个新的增强版函数
  • 使用 @decorator_name 语法糖,可以简洁地应用装饰器。

2. 最简单的装饰器

def my_decorator(func):
def wrapper():
print("函数执行前")
func()
print("函数执行后")
return wrapper
@my_decorator
def say_hello():
print("Hello, World!")
say_hello()

执行结果

函数执行前
Hello, World!
函数执行后

解析

  1. my_decorator 接收 say_hello,返回 wrapper,替换原函数。
  2. wrappersay_hello 前后增加了额外的功能。
  3. @my_decorator 等价于 say_hello = my_decorator(say_hello)

3. 带参数的装饰器

如果被装饰的函数有参数,wrapper 需要支持 *args**kwargs

def my_decorator(func):
def wrapper(*args, **kwargs):
print("执行前")
result = func(*args, **kwargs)
print("执行后")
return result
return wrapper
@my_decorator
def add(a, b):
return a + b
print(add(3, 5))

执行结果

执行前
执行后
8

4. 带参数的装饰器(装饰器本身接受参数)

如果希望控制装饰器行为,可以再封装一层:

def repeat(n):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(n):
func(*args, **kwargs)
return wrapper
return decorator
@repeat(3)
def say_hello():
print("Hello!")
say_hello()

执行结果

Hello!
Hello!
Hello!

5. 使用 functools.wraps 保留原函数信息

装饰器会修改原函数的 __name____doc__,使用 functools.wraps 解决:

import functools
def my_decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
print("执行前")
result = func(*args, **kwargs)
print("执行后")
return result
return wrapper
@my_decorator
def my_function():
"""这是我的测试函数"""
print("执行 my_function")
print(my_function.__name__) # 仍然是 "my_function"
print(my_function.__doc__) # 仍然是 "这是我的测试函数"

6. 类装饰器

装饰器也可以用来实现:

class MyDecorator:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print("执行前")
result = self.func(*args, **kwargs)
print("执行后")
return result
@MyDecorator
def greet(name):
print(f"Hello, {name}!")
greet("Alice")

执行结果

执行前
Hello, Alice!
执行后

7. 多个装饰器嵌套

多个装饰器按从下到上的顺序应用:

def decorator1(func):
def wrapper(*args, **kwargs):
print("装饰器1")
return func(*args, **kwargs)
return wrapper
def decorator2(func):
def wrapper(*args, **kwargs):
print("装饰器2")
return func(*args, **kwargs)
return wrapper
@decorator1
@decorator2
def hello():
print("Hello, world!")
hello()

执行结果

装饰器1
装饰器2
Hello, world!

8. 实际应用场景

(1)日志记录

装饰器可用于自动记录函数调用

def log(func):
def wrapper(*args, **kwargs):
print(f"调用 {func.__name__},参数:{args}, {kwargs}")
result = func(*args, **kwargs)
print(f"返回值:{result}")
return result
return wrapper
@log
def multiply(a, b):
return a * b
print(multiply(3, 4))

执行结果

调用 multiply,参数:(3, 4), {}
返回值:12
12

(2)权限控制

常用于 检查用户权限

def require_permission(role):
def decorator(func):
def wrapper(*args, **kwargs):
if role != "admin":
print("权限不足")
return
return func(*args, **kwargs)
return wrapper
return decorator
@require_permission("user")
def delete_data():
print("数据已删除")
delete_data()

执行结果

权限不足

(3)计算函数执行时间

import time
def timer(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"{func.__name__} 执行时间:{end - start:.5f} 秒")
return result
return wrapper
@timer
def slow_function():
time.sleep(2)
print("函数执行完成")
slow_function()

执行结果

函数执行完成
slow_function 执行时间:2.00012 秒

(4)缓存函数结果

使用 functools.lru_cache缓存计算结果,提升性能:

import functools
@functools.lru_cache(maxsize=3) # 最多缓存3个结果
def fib(n):
if n < 2:
return n
return fib(n-1) + fib(n-2)
print(fib(10))

加速递归计算斐波那契数列


总结

场景 作用
日志 记录函数调用信息
权限控制 限制非管理员访问
性能分析 计算函数运行时间
缓存 加速计算(如 Fibonacci)
重试机制 失败后自动重试

掌握装饰器可以让 Python 代码更优雅、模块化、易维护! 🚀

本文作者:清澈的澈

本文链接:https://www.cnblogs.com/lmc7/p/18703470

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   清澈的澈  阅读(5)  评论(0编辑  收藏  举报
评论
收藏
关注
推荐
深色
回顶
收起
点击右上角即可分享
微信分享提示