当前位置: 首页 > news >正文

Python中内置装饰器

Python 装饰器(Decorator)是一种强大的语法,用于在不修改原函数代码的前提下,动态地增强函数的功能。它本质上是一个高阶函数(接收函数作为参数,并返回一个新函数),通常用于日志记录、权限验证、缓存等场景。

一、装饰器的核心原理

装饰器的作用可以概括为:“包装”原函数,在原函数执行前后添加额外逻辑,同时不改变原函数的调用方式

基本流程:

  1. 定义一个装饰器函数(接收被装饰的函数作为参数)
  2. 在装饰器内部定义一个“包装函数”(实现增强逻辑)
  3. 返回这个包装函数替换原函数

二、基础示例:最简单的装饰器

下面通过一个“计时装饰器”示例,理解装饰器的基本用法:

# 1. 定义装饰器:计算函数执行时间
def timer_decorator(func):# 3. 定义包装函数(包装原函数)def wrapper():import timestart = time.time()  # 执行前:记录开始时间func()  # 调用原函数end = time.time()    # 执行后:记录结束时间print(f"函数执行耗时:{end - start:.2f}秒")# 4. 返回包装函数(替换原函数)return wrapper# 2. 使用装饰器:用@语法修饰目标函数
@timer_decorator
def slow_function():# 模拟耗时操作import timetime.sleep(1)print("函数执行完毕")# 调用被装饰后的函数(调用方式不变)
slow_function()

输出:

函数执行完毕
函数执行耗时:1.00秒

关键点

  • @timer_decorator 等价于 slow_function = timer_decorator(slow_function)
  • 调用 slow_function() 时,实际执行的是装饰器返回的 wrapper() 函数
  • 原函数 slow_function 的功能被保留,同时新增了“计时”功能

三、带参数的函数如何装饰?

如果被装饰的函数有参数,需要在包装函数中传递参数:

def log_decorator(func):# 包装函数接收任意参数 *args 和 **kwargsdef wrapper(*args, **kwargs):print(f"调用函数:{func.__name__},参数:{args}, {kwargs}")result = func(*args, **kwargs)  # 传递参数给原函数print(f"函数返回值:{result}")return result  # 返回原函数的结果return wrapper@log_decorator
def add(a, b):return a + b# 调用带参数的函数
add(3, 5)

输出:

调用函数:add,参数:(3, 5), {}
函数返回值:8

说明

  • *args 接收任意数量的位置参数(如 3, 5
  • **kwargs 接收任意数量的关键字参数(如 a=3, b=5
  • 确保包装函数的参数能覆盖原函数的所有可能参数

四、带参数的装饰器

装饰器本身也可以接收参数,用于动态调整装饰逻辑。需要在原有装饰器外层再嵌套一层函数:

# 带参数的装饰器:允许指定日志前缀
def prefix_log_decorator(prefix):# 第一层:接收装饰器参数def decorator(func):# 第二层:接收被装饰函数def wrapper(*args, **kwargs):print(f"[{prefix}] 调用函数:{func.__name__}")return func(*args, **kwargs)return wrapperreturn decorator# 使用带参数的装饰器
@prefix_log_decorator(prefix="INFO")
def greet(name):return f"Hello, {name}!"greet("kk")

输出:

[INFO] 调用函数:greet

执行逻辑
@prefix_log_decorator("INFO") 等价于:

greet = prefix_log_decorator("INFO")(greet)

下例可以验证上述执行逻辑:

def prefix_log_decorator(prefix):# 第一层:接收装饰器参数def decorator(func):# 第二层:接收被装饰函数def wrapper(*args, **kwargs):print(f"[{prefix}] 调用函数:{func.__name__}")return func(*args, **kwargs)return wrapperreturn decoratordef AaddB(a,b):print(a+b)prefix_log_decorator("INFO")(AaddB)(1,2)

五、保留原函数信息

装饰器会默认替换原函数的元信息(如 __name____doc__),可以用 functools.wraps 修复:

import functoolsdef my_decorator(func):@functools.wraps(func)  # 保留原函数信息def wrapper(*args, **kwargs):return func(*args, **kwargs)return wrapper@my_decorator
def example():"""这是示例函数的文档字符串"""passprint(example.__name__)  # 输出:example(而非 wrapper)
print(example.__doc__)   # 输出:这是示例函数的文档字符串

六、常见应用场景

  1. 日志记录:自动记录函数调用信息、参数、返回值
  2. 权限验证:在函数执行前检查用户权限
  3. 缓存:缓存函数结果,避免重复计算
  4. 性能测试:统计函数执行时间
  5. 输入验证:检查函数参数是否符合要求

总结

  • 装饰器是“包装函数”的工具,核心是不修改原函数代码却能增强其功能
  • 基础语法:@装饰器名 放在函数定义上方
  • 处理参数:用 *args, **kwargs 适配任意参数的函数
  • 带参数的装饰器:需要多一层函数嵌套
  • 最佳实践:用 functools.wraps 保留原函数信息

装饰器是 Python 中“开闭原则”(对扩展开放,对修改关闭)的典型实现,在框架(如 Flask、Django)中被广泛使用。


文章转载自:

http://a0nMYA7U.qfkdt.cn
http://GCxzmJaZ.qfkdt.cn
http://ACUfx42F.qfkdt.cn
http://XsaHG0MQ.qfkdt.cn
http://rUSgJ5FL.qfkdt.cn
http://AlWZ0k5J.qfkdt.cn
http://1QDiqkFc.qfkdt.cn
http://siQj1v5H.qfkdt.cn
http://wos1l7Ia.qfkdt.cn
http://3U08UVmG.qfkdt.cn
http://jYlE4SJv.qfkdt.cn
http://sdMgppOb.qfkdt.cn
http://SpBO5WSk.qfkdt.cn
http://cQyZxFc4.qfkdt.cn
http://ShpTSP6W.qfkdt.cn
http://fgMgwHsM.qfkdt.cn
http://HtLu9xsN.qfkdt.cn
http://ApwPRaDL.qfkdt.cn
http://wocWiZYr.qfkdt.cn
http://TnvoOiar.qfkdt.cn
http://ZFYGaa1k.qfkdt.cn
http://Aw0hZY5N.qfkdt.cn
http://8D4xIV43.qfkdt.cn
http://snf4rdtA.qfkdt.cn
http://DMSKyeJo.qfkdt.cn
http://Ss01VHie.qfkdt.cn
http://E7F4zSJN.qfkdt.cn
http://DwWBcPE6.qfkdt.cn
http://ySJCrNP9.qfkdt.cn
http://3P3q2HBz.qfkdt.cn
http://www.dtcms.com/a/375266.html

相关文章:

  • 鸿蒙NEXT UI高性能开发实战:从原理到优化
  • 影视APP源码 SK影视 安卓+苹果双端APP 反编译详细视频教程+源码
  • Anthropic 支持加州 AI 安全法案
  • 【杂类】应对 MySQL 处理短时间高并发的请求:缓存预热
  • ubuntu 20.04 安装spark
  • 【企业微信】接口报错:javax.net.ssl.SSLHandshakeException
  • uniapp原生插件 TCP Socket 使用文档
  • 京东云-数据盘挂载
  • 【华为OD】Linux发行版的数量
  • 缓冲区漏洞详解
  • 位图转矢量图的实现方法与常用工具解析
  • 设计模式-简单工厂策略装饰器代理
  • 家庭劳务机器人发展阶段与时间预测
  • .NET 单文件程序详解:从原理到实践
  • 新能源汽车充电设备装调与检修仿真教学软件:理虚实融合实训方案
  • 小鹏汽车 vla 算法最新进展
  • C++ 20 视图view笔记
  • HTML 网页静态托管 API 接口文档(可集成到智能体Agent)
  • 在uni-app中使用lottie-web来展示Lottie动画
  • Python数据可视化基础:使用Matplotlib绘制图表
  • CodeBuddy Code深度实战:从零构建智能电商推荐系统的完整开发历程
  • 【Kubernetes知识点】PriorityClass,HPA和CICD
  • 赋能多场景创新:明远智睿H618核心板
  • (C++)数据结构初阶(顺序表的实现)
  • 一手实测,文心x1.1的升级很惊喜啊
  • 【系统分析师】第18章-关键技术:移动应用系统分析与设计(核心总结)
  • echarts 实现柱状图自动滚动展示数据(Vue3)
  • 基于Python的购物商城网站电商管理系统【2026最新】
  • Electron 分发策略:创建安装程序与自动更新
  • IAR 集成开发环境入门指南:字体设置与调试实战