python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > python 内置装饰器

Python 内置装饰器全解析

作者:第六五签

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

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

智能体场景:缓存搜索结果、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 内置装饰器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文