Python 内置装饰器全解析

 更新时间:2026年07月04日 09:44:29   作者:第六五签  
Python的内置装饰器主要分布在内置函数和标准库中,它们能帮我们以极简的代码为函数或类添加强大功能,本文给大家介绍Python内置装饰器全解析,感兴趣的朋友跟随小编一起看看吧

Python 的「内置装饰器」通常分为两类:

  1. 原生核心装饰器:Python 语法内置,无需导入即可直接使用,是面向对象编程的核心工具;
  2. 标准库装饰器:随 Python 官方标准库发布,无需额外安装,导入对应模块即可使用,覆盖性能优化、代码简化、架构设计等场景。

下面逐一讲解核心常用的装饰器。

一、原生核心装饰器(无需导入)

这三个是 Python 最基础的内置装饰器,全部作用于类的方法,无需 import 直接使用。

1. @property

作用:将类的方法「伪装」成属性访问,用来实现受控的 getter / setter / deleter,封装属性的校验、计算、动态生成逻辑。
它是 Python 实现「封装」特性的首选方式,避免直接暴露类的内部变量。

示例(结合配置类场景):

class AgentConfig:
    def __init__(self, temperature: float):
        self._temperature = temperature
    @property
    def temperature(self):
        """读取时像访问属性一样:config.temperature"""
        return self._temperature
    @temperature.setter
    def temperature(self, value: float):
        """设置参数时自动做范围校验"""
        if not 0 <= value <= 2:
            raise ValueError("temperature 必须在 0~2 之间")
        self._temperature = value

使用方式

config = AgentConfig(0.7)
print(config.temperature)  # 像属性一样读取,不用写 get_temperature()
config.temperature = 1.5  # 像属性一样赋值,自动触发校验逻辑

2. @classmethod

作用:标记为「类方法」,方法属于类本身而非实例。第一个参数固定为 cls(代表当前类),无需实例化即可通过类名直接调用,常用于实现多种构造方式(工厂模式)。
你之前问过的 from_env 就是典型的类方法应用。

3. @staticmethod

作用:标记为「静态方法」,它既不接收 self 也不接收 cls,本质是放在类命名空间里的普通工具函数,和类本身没有强制绑定,只是逻辑上归属于该类。
适合存放和类相关、但不需要访问类/实例属性的工具逻辑。

示例

class AgentConfig:
    @staticmethod
    def validate_temperature(value: float) -> bool:
        """独立的参数校验工具,和实例/类无关"""
        return 0 <= value <= 2
# 直接通过类调用,无需创建实例
print(AgentConfig.validate_temperature(0.7))  # True

二、标准库高频内置装饰器

这些装饰器来自 Python 官方标准库,无需额外安装,导入即可使用,是工程化项目的高频工具。

(一)dataclasses 模块:@dataclass

定位:最常用的类装饰器(Python 3.7+ 加入),自动为数据类生成 __init____repr____eq__ 等魔术方法,大幅简化数据结构类的代码,避免重复的样板代码。

智能体场景:定义配置、消息体、搜索结果、工具返回值等数据结构的首选。

示例

from dataclasses import dataclass
from typing import Optional
@dataclass
class SearchResult:
    title: str
    url: str
    snippet: str
    score: Optional[float] = None
# 直接使用,无需手动写构造函数
result = SearchResult(
    title="华为最新手机",
    url="https://example.com",
    snippet="Mate 70 系列发布"
)
print(result)
# SearchResult(title='华为最新手机', url='https://example.com', snippet='Mate 70 系列发布', score=None)

(二)functools 模块:工具装饰器集合

functools 是 Python 内置的高阶函数工具库,提供了多个工程化必备的装饰器。

1. @functools.wraps

作用:写自定义装饰器时的标配,用来保留原函数的元信息(函数名、文档字符串、参数签名等),避免装饰后的函数丢失原有属性。
只要你自己写装饰器,就必须用它。

示例

import time
from functools import wraps
def timer(func):
    @wraps(func)  # 保留原函数的元信息
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        print(f"{func.__name__} 耗时: {time.time()-start:.2f}s")
        return result
    return wrapper
@timer
def search(query: str):
    """搜索函数"""
    time.sleep(0.1)
    return f"搜索结果: {query}"
print(search.__name__)  # 保留原函数名:search(不加wraps会变成wrapper)
print(search.__doc__)   # 保留原文档:搜索函数

2. @functools.lru_cache / @functools.cache

作用:函数结果缓存装饰器,自动记住函数的输入-输出映射,相同输入再次调用时直接返回缓存结果,避免重复计算/重复调用,大幅提升性能。

  • @cache:Python 3.9+ 可用,等价于 @lru_cache(maxsize=None),无上限缓存。
  • @lru_cache:可设置最大缓存数量,自动淘汰最少使用的缓存。

智能体场景:缓存搜索结果、RAG 检索结果、重复的大模型调用,减少重复请求。

示例

from functools import lru_cache
@lru_cache(maxsize=100)  # 最多缓存100个结果
def search_web(query: str) -> str:
    """模拟网络搜索,相同query不会重复请求"""
    print(f"执行真实搜索: {query}")
    return f"{query} 的搜索结果"
# 第一次调用会执行真实搜索
search_web("华为最新手机")
# 第二次相同输入,直接返回缓存,不会再打印"执行真实搜索"
search_web("华为最新手机")

注意:只能缓存参数可哈希的函数(参数是字符串、数字、元组等),列表、字典等不可哈希类型不能直接用。

3. @functools.total_ordering

作用:类装饰器,只需给类实现 __eq__ 和一个比较方法(如 __lt__ 小于),自动补全剩余的 <=>>= 全部比较运算符,简化代码。
常用于给搜索结果、评分项定义排序逻辑。

4. @functools.singledispatch

作用:实现单分派泛函数——根据函数第一个参数的类型,自动分发到不同的处理逻辑,相当于实现了「按类型重载」的效果。
适合写统一入口、但不同类型输入处理逻辑不同的函数。

(三)abc 模块:@abstractmethod

作用:定义抽象基类的抽象方法,强制所有子类必须实现该方法,否则无法实例化。
是面向对象设计中「接口规范」「基类模板」的核心工具,你之前的 Agent 基类就是典型应用场景。

(四)contextlib 模块:@contextmanager

作用:将生成器函数转换成上下文管理器,替代手动编写 __enter__ / __exit__ 方法,大幅简化上下文管理器的实现。
常用于资源管理(计时、临时目录、会话连接等)。

示例(计时上下文):

from contextlib import contextmanager
import time
@contextmanager
def timer(name: str):
    start = time.time()
    yield  # 进入上下文执行代码,yield 之后是退出逻辑
    print(f"{name} 总耗时: {time.time()-start:.2f}s")
# 使用方式
with timer("搜索流程"):
    time.sleep(0.2)

三、其他常用标准库装饰器

装饰器所属模块核心作用
@enum.uniqueenum约束枚举类的取值唯一,避免重复枚举值
@typing.overloadtyping为函数定义多组类型重载注解,供静态类型检查使用,运行时无实际效果
@asyncio.coroutineasyncio旧版异步协程装饰器,已被 async/await 语法取代,仅兼容老代码

四、项目高频总结

最常用的装饰器按优先级排序:

  1. 数据结构@dataclass(定义消息、配置、结果)
  2. 类设计@property@classmethod@abstractmethod(基类与封装)
  3. 性能优化@lru_cache(缓存重复调用)
  4. 自定义工具@functools.wraps(写自己的装饰器)
  5. 资源管理@contextmanager(上下文逻辑)

到此这篇关于Python 内置装饰器全解析的文章就介绍到这了,更多相关python 内置装饰器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • flask框架视图函数用法示例

    flask框架视图函数用法示例

    这篇文章主要介绍了flask框架视图函数用法,结合实例形式分析了flask框架视图函数常见配置与使用技巧,需要的朋友可以参考下
    2018-07-07
  • Python学习之不同数据类型间的转换总结

    Python学习之不同数据类型间的转换总结

    类型转换,就是将自身的数据类型变成新的数据类型,并拥有新的数据类型的所有功能的过程。本文将详细为大家介绍如何在Python中实现不同数据类型的转换,感兴趣的可以了解一下
    2022-03-03
  • 详解Python中的List 2

    详解Python中的List 2

    这篇文章主要为大家介绍了Python中的List,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-12-12
  • python之如何查找多层嵌套字典的值

    python之如何查找多层嵌套字典的值

    这篇文章主要介绍了python之如何查找多层嵌套字典的值问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • Python使用scipy.fft进行大学经典的傅立叶变换

    Python使用scipy.fft进行大学经典的傅立叶变换

    傅里叶变换是在高数是一个很重要的知识点,本文将介绍Python使用scipy.fft进行大学经典的傅立叶变换,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-06-06
  • Python3之字符串比较_重写cmp函数方式

    Python3之字符串比较_重写cmp函数方式

    这篇文章主要介绍了Python3之字符串比较_重写cmp函数方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-02-02
  • Python中mmap模块处理大文本的操作方法

    Python中mmap模块处理大文本的操作方法

    这篇文章主要介绍了Python中mmap模块(处理大文本),将一个普通文件映射到内存中,通常在需要对文件进行频繁读写时使用,这样用内存映射读写取代I/O缓存读写,以获得较高的性能,需要的朋友可以参考下
    2023-02-02
  • Python使用Pyecharts绘制交互式中国地图的流程解析

    Python使用Pyecharts绘制交互式中国地图的流程解析

    Pyecharts作为基于ECharts的Python可视化库,提供三大核心优势,即零代码交互,多级地图支持和高度定制化,下面我们就来看看如何使用Pyecharts绘制交互式中国地图吧
    2026-02-02
  • 如何使用python socket模块实现简单的文件下载

    如何使用python socket模块实现简单的文件下载

    这篇文章主要介绍了如何使用python socket模块实现简单的文件下载,帮助大家更好的理解和学习python,感兴趣的朋友可以了解下
    2020-09-09
  • Python functools模块学习总结

    Python functools模块学习总结

    这篇文章主要介绍了Python functools模块学习总结,本文讲解了functools.partial、functool.update_wrapper、functool.wraps、functools.reduce、functools.cmp_to_key、functools.total_ordering等方法的使用实例,需要的朋友可以参考下
    2015-05-05

最新评论