跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Python

Python 装饰器的 10 个应用场景

Python 装饰器的核心概念及十大应用场景,包括日志记录、性能测试、数据缓存、输入验证、授权认证、参数修改、错误处理、单例模式、事件监听和异步编程。文章提供了完整的代码示例,涵盖了基础用法、带参数装饰器、类装饰器以及调试注意事项。通过合理使用装饰器,开发者可以在不修改原代码的情况下增强函数功能,提升代码的可维护性和扩展性。

moshang发布于 2025/2/6更新于 2026/10/2491 浏览
Python 装饰器的 10 个应用场景

Python 装饰器的 10 个应用场景详解

装饰器本质上是一个高阶函数,它接受一个函数作为参数并返回一个新函数。通过使用 @ 符号语法糖,我们可以将装饰器应用于任何函数或类,从而在不修改原函数代码的前提下增强其功能。在实际开发中,合理使用装饰器可以显著提高代码的可读性和可维护性。

在使用自定义装饰器时,建议结合 functools.wraps 来保留原函数的元数据(如名称、文档字符串等),避免调试困难。

基础示例

import functools

def my_decorator(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        print("Something is happening before the function is called.")
        result = func(*args, **kwargs)
        print("Something is happening after the function is called.")
        return result
    return wrapper

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

say_hello()

常见应用场景

1. 日志记录

装饰器可以用来记录函数的调用细节,这在调试和监控应用时非常有用。通过记录输入参数和返回值,可以快速定位问题。

import logging

logging.basicConfig(level=logging.INFO)

def log_decorator(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        logging.info(f"{func.__name__} was called with args={args}, kwargs={kwargs}")
        result = func(*args, **kwargs)
        logging.info(f" returned ")
         result
     wrapper


 ():
     x + y
{func.__name__}
{result}
return
return
@log_decorator
def
add
x, y
return

2. 性能测试

使用装饰器来测量函数执行时间,对于性能分析和瓶颈定位非常有用。

import time

def timing_decorator(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        elapsed = end_time - start_time
        print(f"{func.__name__} took {elapsed:.4f} seconds")
        return result
    return wrapper

3. 数据缓存

装饰器可以用于缓存函数的结果,避免重复计算,特别适用于纯函数(Pure Functions)。Python 标准库提供了 lru_cache 实现。

from functools import lru_cache

@lru_cache(maxsize=128)
def fib(n):
    if n < 2:
        return n
    return fib(n-1) + fib(n-2)

4. 输入验证

确保函数接收有效输入,可以在函数内部逻辑之前进行类型检查或范围校验,提高健壮性。

def validate_decorator(func):
    @functools.wraps(func)
    def wrapper(x, y):
        if not isinstance(x, int) or not isinstance(y, int):
            raise TypeError("Input must be integers")
        return func(x, y)
    return wrapper

@validate_decorator
def multiply(x, y):
    return x * y

5. 授权与身份验证

检查用户是否有执行函数的权限,常用于 Web 框架中的路由保护或 API 接口鉴权。

def auth_decorator(required_role='admin'):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(user, *args, **kwargs):
            if user.get('role') == required_role:
                return func(user, *args, **kwargs)
            else:
                raise PermissionError("You do not have permission")
        return wrapper
    return decorator

@auth_decorator(required_role='admin')
def delete_resource(user, resource_id):
    pass

6. 参数修改

修改函数的输入参数,例如统一格式化时间戳或转换数据类型。

def modify_args_decorator(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        # Example: Double all numeric arguments
        new_args = [arg * 2 if isinstance(arg, (int, float)) else arg for arg in args]
        return func(*new_args, **kwargs)
    return wrapper

7. 错误处理

捕获函数中的异常并进行处理,防止程序崩溃,同时记录错误堆栈信息。

def error_handling_decorator(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except Exception as e:
            print(f"Error occurred in {func.__name__}: {e}")
            return None
    return wrapper

8. 单例模式

确保类的实例只创建一次,常用于数据库连接池或配置管理器。

def singleton(cls):
    instances = {}
    @functools.wraps(cls)
    def wrapper(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return wrapper

@singleton
class Database:
    def __init__(self):
        self.connection = "Connected"

9. 事件监听

在特定事件发生时执行额外的操作,常用于解耦业务逻辑与通知逻辑。

def event_listener(event_name):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            # Simulate event check
            if True: 
                return func(*args, **kwargs)
        return wrapper
    return decorator

10. 异步编程

使同步函数能够异步执行,或者为异步函数添加等待逻辑,配合 asyncio 使用。

import asyncio

async def async_decorator(func):
    @functools.wraps(func)
    async def wrapper(*args, **kwargs):
        await asyncio.sleep(0.1)
        return await func(*args, **kwargs)
    return wrapper

@async_decorator
async def fetch_data():
    return "Data"

进阶技巧

带参数的装饰器

当需要传递参数给装饰器本身时,需要使用三层嵌套函数。

def repeat(times):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            for _ in range(times):
                func(*args, **kwargs)
        return wrapper
    return decorator

类装饰器

除了函数装饰器,还可以使用类来实现装饰器逻辑,通常用于更复杂的状态管理。

class CountCalls:
    def __init__(self, func):
        functools.update_wrapper(self, func)
        self.func = func
        self.count = 0

    def __call__(self, *args, **kwargs):
        self.count += 1
        print(f"Call {self.count} of {self.func.__name__}")
        return self.func(*args, **kwargs)

@CountCalls
def say_hi():
    print("Hi")

调试注意事项

在使用装饰器时,如果未正确使用 functools.wraps,会导致 __name__ 和 __doc__ 丢失,增加调试难度。此外,多层装饰器叠加时,需要注意执行顺序:从内到外依次包裹。在生产环境中,应充分考虑装饰器对性能的影响,避免在高频调用的路径上引入过重的逻辑。

总结

装饰器是 Python 中一个强大而灵活的工具,它可以在不改变原有代码结构的前提下,为函数增加额外的功能。通过掌握装饰器的使用,你可以使你的 Python 代码更加高效、优雅和可维护。注意在生产环境中使用装饰器时,应充分考虑其对性能的影响以及异常处理的完备性。

目录

  1. Python 装饰器的 10 个应用场景详解
  2. 基础示例
  3. 常见应用场景
  4. 1. 日志记录
  5. 2. 性能测试
  6. 3. 数据缓存
  7. 4. 输入验证
  8. 5. 授权与身份验证
  9. 6. 参数修改
  10. 7. 错误处理
  11. 8. 单例模式
  12. 9. 事件监听
  13. 10. 异步编程
  14. 进阶技巧
  15. 带参数的装饰器
  16. 类装饰器
  17. 调试注意事项
  18. 总结

更多推荐文章

查看全部
  • Spring Boot+Vue3 多租户自助门店系统:IoT 硬件集成与无人值守方案
  • LangGraph工具调用实战:手把手教你实现ReAct搜索机器人
  • 构建多模态搜索与 RAG 系统实战指南
  • Go 工作区 go.work 简介与使用指南
  • LangChain Agent Skills 实战:构建 GitHub 仓库分析能力
  • C++ STL 算法实战:查找、排序与数值处理
  • C++ AVL 树详解:概念、插入与旋转
  • Linux 磁盘及文件系统管理基础
  • 安装 Conda 与 VSCode 配置 Python 开发环境
  • MySQL 约束详解:非空、主键与外键的核心作用
  • JavaScript 比较与逻辑运算符基础
  • 图论算法详解:BFS、DFS 及最小生成树
  • Python 入门教程:核心特性、学习路线与实战建议
  • C++ 智能指针详解:原理、实现与使用
  • Alpine Linux apk 包管理器使用指南
  • 二叉树算法实战:美国血统重建与深度宽度计算
  • 腾讯大模型「实用」路线揭示企业 AI 应用新方向
  • OpenClaw 技术解析:构建 AI 行动型智能体的架构与实践
  • AI 大模型将如何重塑日常生活与移动端体验
  • GitHub 界面本地化插件:效率提升与全中文体验技巧

相关免费在线工具

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online