当前位置: 首页>>AGI专栏>>正文


Python装饰模式用法及代码示例

以下是 Python 装饰器模式 的详细用法解析与实用示例,涵盖函数装饰器、类装饰器及多层嵌套场景,帮助灵活扩展对象功能:

一、装饰模式的核心思想

  • 定义:动态地为对象添加额外职责,且不改变其原有结构。
  • 优势:避免继承导致的类爆炸,支持运行时功能组合。
  • Python特性:通过 @ 语法糖简化实现,本质是 高阶函数 或 类包装

二、函数装饰器实现

1. 基础装饰器(无参)

def logger(func):
    def wrapper(*args, **kwargs):
        print(f"开始执行: {func.__name__}")
        result = func(*args, **kwargs)
        print(f"执行结束: {func.__name__}")
        return result
    return wrapper

@logger
def add(a, b):
    return a + b

print(add(2, 3))  
# 输出:
# 开始执行: add
# 执行结束: add
# 5

2. 带参数的装饰器

def repeat(times):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(times):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

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

greet("Alice")
# 输出:
# Hello, Alice!
# Hello, Alice!
# Hello, Alice!

三、类装饰器实现

1. 装饰器类(基于 __call__ 方法)

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

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

@Timer
def heavy_computation(n):
    return sum(i*i for i in range(n))

heavy_computation(10**6)  # 输出: heavy_computation 耗时: 0.12秒

2. 装饰器类(带参数)

class PermissionCheck:
    def __init__(self, role):
        self.role = role

    def __call__(self, func):
        def wrapper(*args, **kwargs):
            if self.role == "admin":
                return func(*args, **kwargs)
            else:
                raise PermissionError("权限不足")
        return wrapper

@PermissionCheck(role="admin")
def delete_file(filename):
    print(f"删除文件: {filename}")

delete_file("test.txt")  # 输出: 删除文件: test.txt

@PermissionCheck(role="user")
def read_file(filename):
    print(f"读取文件: {filename}")

read_file("test.txt")  # 抛出 PermissionError

四、多层装饰器执行顺序

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

@decorator1
@decorator2
def my_func():
    pass

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

示例

def bold(func):
    def wrapper():
        return "<b>" + func() + "</b>"
    return wrapper

def italic(func):
    def wrapper():
        return "<i>" + func() + "</i>"
    return wrapper

@bold
@italic
def say_hello():
    return "Hello"

print(say_hello())  # 输出: <b><i>Hello</i></b>

五、装饰器的典型应用场景

  1. 日志记录与性能监控
    跟踪函数执行时间和参数。
  2. 权限验证
    限制接口访问权限(如用户角色检查)。
  3. 缓存与记忆化
    存储函数结果避免重复计算:

    from functools import lru_cache
    
    @lru_cache(maxsize=128)
    def fibonacci(n):
        if n < 2:
            return n
        return fibonacci(n-1) + fibonacci(n-2)
  4. 路由注册(Web框架)
    Flask 框架的路由装饰器:

    @app.route("/")
    def home():
        return "Welcome"
  5. 输入验证与格式化
    确保函数参数符合预期:

    python
    Copy
    def validate_int_args(func):
        def wrapper(*args):
            if all(isinstance(arg, int) for arg in args):
                return func(*args)
            else:
                raise ValueError("参数必须为整数")
        return wrapper

六、注意事项与调试技巧

  1. 保留元信息
    使用 functools.wraps 保持原函数属性(如 __name__):

    from functools import wraps
    
    def debug(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            print(f"调用 {func.__name__}")
            return func(*args, **kwargs)
        return wrapper
  2. 处理带状态的装饰器
    类装饰器适合需保存状态的场景(如计数器):

    class Counter:
        def __init__(self, func):
            self.func = func
            self.count = 0
    
        def __call__(self, *args, **kwargs):
            self.count += 1
            print(f"执行次数: {self.count}")
            return self.func(*args, **kwargs)
    
    @Counter
    def example():
        pass
  3. 避免循环装饰
    多层装饰可能引发意外行为,需谨慎设计执行顺序。

总结

Python 装饰器模式通过 高阶函数 或 类包装 实现功能扩展,结合 @ 语法糖可显著提升代码可读性。合理使用装饰器能实现以下目标:

  • 代码复用:抽离通用逻辑(如日志、权限)。
  • 关注点分离:业务代码与辅助功能解耦。
  • 动态扩展:运行时灵活组合功能模块。

掌握装饰器模式是编写优雅 Python 代码的关键技能!

本文由《纯净天空》出品。文章地址: https://vimsky.com/article/4851.html,转载请注明来源链接。