Python装饰器(Decorator)1 —— 装饰函数

相关链接
1. 装饰函数
2. 装饰方法
3. 装饰类

Python装饰器(Decorator)是一种强大的语法特性,允许在不修改原函数代码的情况下,动态地增强函数或方法的功能。以下是装饰器的核心概念和用法:

一、装饰器基础

1. 最简单的装饰器

装饰器本质上是一个高阶函数,它接受一个函数作为输入,返回一个新的函数(或可调用对象)。

示例1:最简单的装饰器
def my_decorator(func):
    def wrapper():
        print("函数执行前...")
        func()
        print("函数执行后...")
    return wrapper

@my_decorator
def say_hello():
    print("Hello!")

say_hello()
输出:
函数执行前...
Hello!
函数执行后...

2. 处理带参数的函数

如果被装饰的函数有参数,需要在内部函数(如wrapper)中使用*args和**kwargs接收任意参数。

示例2:支持参数的装饰器
def decorator_with_args(func):
    def wrapper(*args, **kwargs):
        print("装饰器:准备执行函数")
        result = func(*args, **kwargs)
        print("装饰器:函数执行完毕")
        return result
    return wrapper

@decorator_with_args
def greet(name):
    print(f"Hello, {name}!")

greet("Alice")
输出:
装饰器:准备执行函数
Hello, Alice!
装饰器:函数执行完毕

3. 带参数的装饰器

若装饰器本身需要参数,需要再嵌套一层函数来接收参数。

示例3:装饰器接受参数
def repeat(n_times):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(n_times):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

@repeat(n_times=3)
def say_hi():
    print("Hi!")

say_hi()
输出:
Hi!
Hi!
Hi!

4. 保留原函数元信息

装饰器会覆盖原函数的元信息(如__name__),使用functools.wraps解决此问题。

示例4:保留原函数元信息
from functools import wraps

def preserve_metadata(func):
    @wraps(func)  # 保留原函数的元信息
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs)
    return wrapper

@preserve_metadata
def example():
    """示例函数"""
    pass

print(example.__name__)  # 输出 "example"
print(example.__doc__)   # 输出 "示例函数"
输出:
example
示例函数

5. 类作为装饰器

类也可以作为装饰器,需实现__call__方法。

示例5:类实现的装饰器
import time

class TimerDecorator:
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        start = time.time()
        result = self.func(*args, **kwargs)
        end = time.time()
        print(f"{self.func.__name__} 执行耗时: {end - start:.2f}秒")
        return result

@TimerDecorator
def slow_function():
    time.sleep(1)

slow_function()
输出:
slow_function 执行耗时: 1.00秒

6. 装饰器的执行顺序

多个装饰器按照__从下到上__的顺序执行(靠近函数定义的先执行)。

@decorator1
@decorator2
def my_func():
    pass

# 等效于:my_func = decorator1(decorator2(my_func))

二、装饰器的作用

  • 代码复用:为多个函数统一添加日志、计时、权限验证等功能。
  • 分离关注点:将业务逻辑与辅助功能(如日志)分离。
  • 动态行为:运行时修改函数行为。

三、 常见应用场景

  • 日志记录:记录函数调用信息。
  • 性能测试:统计函数执行时间。
  • 权限校验:检查用户权限。
  • 缓存:缓存函数结果(如functools.lru_cache)。
  • 路由注册:Web框架(如Flask)中的路由定义。

下一篇: 2. 装饰方法

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值