当前位置:首页 > Python > 正文内容

Python装饰器的进阶应用与实战技巧

admin2周前 (03-22)Python22

装饰器(Decorator)是Python中最优雅的特性之一,它允许我们在不修改原有函数代码的前提下,为函数添加额外的功能。本文将深入探讨装饰器的进阶用法,展示如何编写实用的装饰器来提升代码质量。

在实际开发中,装饰器常用于日志记录、性能监测、权限校验、缓存管理等场景。通过本文的学习,你将掌握装饰器的核心概念,并能够编写出自己的实用装饰器。

一、装饰器的基础原理

装饰器本质上是一个接受函数作为参数,并返回一个新函数的高阶函数。这个新函数通常会在调用原函数前后执行一些额外的操作

基本的装饰器模板如下:

def my_decorator(func):
    def wrapper(*args, **kwargs):
        # 在原函数执行前的操作
        result = func(*args, **kwargs)
        # 在原函数执行后的操作
        return result
    return wrapper

使用 functools.wraps 保留原函数的元数据,这是一个最佳实践:

import functools

def my_decorator(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        # 装饰器逻辑
        return func(*args, **kwargs)
    return wrapper

二、带参数的装饰器

实际开发中,我们经常需要创建可以接收参数的装饰器。下面是一个可以重试失败的装饰器示例:

import functools
import time

def retry(max_attempts=3, delay=1):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            for attempt in range(max_attempts):
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    if attempt == max_attempts - 1:
                        raise
                    print(f"重试 {attempt   1}/{max_attempts} 失败,{e}")
                    time.sleep(delay)
            return wrapper
        return decorator

@retry(max_attempts=3, delay=2)
def unstable_operation():
    import random
    if random.random() < 0.7:
        raise ConnectionError("网络不稳定")
    return "操作成功"

这个装饰器可以自动重试失败的函数,适用于网络请求、数据库连接等不稳定操作

三、单例模式的装饰器

单例模式可以确保一个类只有一个实例,在缓存、数据库连接池等场景中非常有用。下面是一个单例缓存装饰器:

import functools

def singleton(class_):
    instances = {}
    def get_instance(*args, **kwargs):
        if class_ not in instances:
            instances[class_] = class_(*args, **kwargs)
        return instances[class_]
    return get_instance

@singleton
class Database:
    def __init__(self):
        self.connected = False
        self.connection_count = 0
        
    def connect(self):
        if not self.connected:
            self.connected = True
            self.connection_count  = 1
            print(f"建立新的数据库连接 ({self.connection_count})")
        else:
            print("使用已有的连接")

使用示例:

db1 = Database()
db1.connect()
# 输出: 建立新的数据库连接 (1)

db2 = Database()
db2.connect()
# 输出: 使用已有的连接

print(db1 is db2)  # True

四、智能缓存装饰器

缓存是提升性能的常用手段,下面是一个支持过期时间的智能缓存装饰器:

import functools
import time
from datetime import datetime, timedelta

def timed_cache(seconds=60):
    def decorator(func):
        cache = {}
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            # 生成缓存键
            key = str(args)   str(sorted(kwargs.items()))
            
            # 检查缓存
            now = datetime.now()
            if key in cache:
                cached_time, value = cache[key]
                if now - cached_time < timedelta(seconds=seconds):
                    return value
            
            # 计算并缓存
            result = func(*args, **kwargs)
            cache[key] = (now, result)
            return result
        return wrapper
    return decorator

@timed_cache(seconds=5)
def expensive_computation(n):
    print(f"计算 fibonacci({n})…")
    time.sleep(1)  # 模拟昂贵操作
    if n <= 1:
        return n
    return expensive_computation(n-1)   expensive_computation(n-2)

五、性能监测装饰器

性能监测是优化代码的重要工具,下面是一个可以记录函数执行时间的装饰器:

import functools
import time
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

def log_execution_time(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        %duration = end_time - start_time
        logger.info(f"函数 {func.__name__} 执行时间: {duration:.4f} 秒")
        return result
    return wrapper

@log_execution_time
def process_data(data):
    time.sleep(0.5)
    return [x * 2 for x in data]

六、权限校验装饰器

在Web应用或API开发中,权限校验是必不可少的。下面是一个基于角色的权限校验装饰器:

import functools

def require_role(*required_roles):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(user, *args, **kwargs):
            if not hasattr(user, 'roles'):
                raise PermissionError("用户缺角色信息")
            if not any(role in user.roles for role in required_roles):
                raise PermissionError(f"需要以下角色之一: {required_roles}")
            return func(user, *args, **kwargs)
        return wrapper
    return decorator

class User:
    def __init__(self, name, roles):
        self.name = name
        self.roles = roles

@require_role("admin", "editor")
def edit_article(user, article_id):
):
    return f"{user.name} 正在编辑文章 {article_id}"

admin_user = User("张三", ["admin"])
guest_user = User("李四", ["guest"])

edit_article(admin_user, 123)  # 成功
edit_article(guest_user, 123)  # 抛出 PermissionError

七、装饰器链与组合

Python支持多个装饰器的叠加使用,它们会从内到外依次执行:

@log_execution_time
@retry(max_attempts=2)
@timed_cache(seconds=30)
def complex_api_call(url):
    # 模拟API调用
    time.sleep(0.2)
    return f"Data from {url}"

执行顺序是: timed_cache → retry → log_execution_time

八、类装饰器

除了函数装饰器,Python还支持类装饰器,它可以用来修改类的行为:

def add_str_method(cls):
    def __str__(self):
        return f"[{cls.__name__}] {self.__dict__}"
    cls.__str__ = __str__
    return cls

@add_str_method
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

p = Person("王五", 30)
print(p)  # [Person] {\name':                                            

相关文章

[Python 教程] Python 网络请求与爬虫基础

Python 网络请求与爬虫基础 requests 是 Python 最常用的 HTTP 库。本文介绍网络请求和爬虫的基础知识。 一、基础请求 import requests # GET 请求 r...

Python 装饰器进阶:从理解到实战

装饰器是 Python 中一个非常强大的特性,它允许你在不修改原函数代码的情况下,为函数添加额外的功能。很多开发者虽然用过装饰器,但对其底层原理和高级用法理解不深。本文将从基础出发,深入讲解装饰器的工...

Python 数据处理三部曲:从清洗到可视化的实战指南

在现代数据驱动的工作场景中,无论是处理实验数据、分析用户行为,还是监控业务指标,高效的数据处理能力都是不可或缺的。Python 提供了一套完整的数据处理工具链,其中 NumPy、Pandas 和 Ma...

Python 异步编程完全指南:从同步到异步

# Python 异步编程完全指南:从同步到异步 # 简介 ## 异步编程的核心概念 ## 基础异步代码示例 ## 并发与并行的区分 ## 异步文件操作 ## 异步数据库操作 ## 异步...

Python 装饰器高级实战:从基础到精通的5个实用技巧

引言:为什么要深入掌握装饰器? 装饰器是 Python 中最优雅的元编程工具之一,它能在不修改原函数代码的情况下,动态地增加功能。很多开发者都知道如何使用 @timer 计时或 @cache 缓存,...

Python装饰器完全指南:从原理到实战

Python 装饰器(Decorator)是 Python 中最强大也是最优雅的特性之一。它允许你在不修改原函数代码的情况下,动态地给函数添加功能。这种设计模式体现了 AOP(面向切面编程)的思想,让...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。