Python 内置装饰器

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

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

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


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

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

1. @property

作用 :将类的方法「伪装」成属性访问,用来实现受控的 getter / setter / deleter,封装属性的校验、计算、动态生成逻辑。

它是 Python 实现「封装」特性的首选方式,避免直接暴露类的内部变量。

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

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

使用方式

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

2. @classmethod

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

你之前问过的 from_env 就是典型的类方法应用。

3. @staticmethod

作用 :标记为「静态方法」,它既不接收 self 也不接收 cls,本质是放在类命名空间里的普通工具函数 ,和类本身没有强制绑定,只是逻辑上归属于该类。

适合存放和类相关、但不需要访问类/实例属性的工具逻辑。

示例

python 复制代码
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__ 等魔术方法,大幅简化数据结构类的代码,避免重复的样板代码。

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

示例

python 复制代码
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

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

只要你自己写装饰器,就必须用它。

示例

python 复制代码
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 检索结果、重复的大模型调用,减少重复请求。

示例

python 复制代码
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__ 方法,大幅简化上下文管理器的实现。

常用于资源管理(计时、临时目录、会话连接等)。

示例(计时上下文):

python 复制代码
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.unique enum 约束枚举类的取值唯一,避免重复枚举值
@typing.overload typing 为函数定义多组类型重载注解,供静态类型检查使用,运行时无实际效果
@asyncio.coroutine asyncio 旧版异步协程装饰器,已被 async/await 语法取代,仅兼容老代码

四、项目高频总结

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

  1. 数据结构@dataclass(定义消息、配置、结果)
  2. 类设计@property@classmethod@abstractmethod(基类与封装)
  3. 性能优化@lru_cache(缓存重复调用)
  4. 自定义工具@functools.wraps(写自己的装饰器)
  5. 资源管理@contextmanager(上下文逻辑)
相关推荐
取经蜗牛1 小时前
Python 第一阶段完全指南:从零到第一个实用工具
开发语言·python
创世宇图1 小时前
【Python工程化实战】OpenTelemetry 在 Python 中的全链路追踪落地:从埋点到可视化的完整实战指南
python·分布式链路追踪·性能监控·opentelemetry·微服务可观测性
dog2502 小时前
从重尾到截断流量模型的演进
开发语言·php
qq_401700412 小时前
Qt QSS 完全入门写出漂亮界面以及解决样式不生效问题
开发语言·qt
许彰午2 小时前
72_Python爬虫基础BeautifulSoup
爬虫·python·beautifulsoup
zhanghongyi_cpp3 小时前
10. 实验书3.4.2 筛选达到预警阈值的病虫害数据
python
我是一颗柠檬3 小时前
【Java项目技术亮点】覆盖索引与索引下推优化
android·java·开发语言
tuddy7894643 小时前
Codex++ 安全边界探秘:从模型能力到风险防御
人工智能·python·安全
2601_962440843 小时前
计算机毕业设计之健身房管理系统的设计与实现
java·开发语言·课程设计·旅游·宠物
C++、Java和Python的菜鸟3 小时前
第1章 集合高级
java·jvm·python