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

day27 python 装饰器

目录

一、装饰器的基本概念

示例:用装饰器优化质数查找函数

二、装饰器的高级用法

1. 支持任意参数的装饰器

2. 装饰器的返回值处理


在 Python 编程中,装饰器是一个非常强大的功能,它可以让其他函数或方法在不需要做任何代码修改的前提下增加额外功能。装饰器本质上是一个 Python 函数,它遵循“不要重复自己”(DRY)的原则,通过封装可复用的功能,使代码更加简洁、可读性更高。

一、装饰器的基本概念

装饰器本质上是一个高阶函数,它接收一个函数作为参数,并返回一个新函数来替代原函数。这个新函数需要保留原函数的调用方式(参数和返回值),同时在原函数执行前后添加额外逻辑(如计时、日志等)。

示例:用装饰器优化质数查找函数

假设我们需要计算 2 到 9999 的所有质数,并打印找到这些数所需的时间。普通的实现方式如下:

import timedef is_prime(num):if num < 2:return Falseelif num == 2:return Trueelse:for i in range(2, num):if num % i == 0:return Falsereturn Truedef prime_nums():t1 = time.time()for i in range(2, 10000):if is_prime(i):print(i)t2 = time.time()print(f"执行时间:{t2 - t1}秒")prime_nums()

在这个例子中,time 模块的代码与质数查找的逻辑混杂在一起,使得代码可读性较差。如果我们将计时功能通过装饰器实现,代码会更加清晰:

import time# 定义一个装饰器
def display_time(func):def wrapper():start_time = time.time()func()  # 调用原函数end_time = time.time()print(f"执行时间: {end_time - start_time} 秒")return wrapper# 使用装饰器
@display_time
def prime_nums():for i in range(2, 10000):if is_prime(i):print(i)prime_nums()

装饰器的底层逻辑是将原函数传递给装饰器函数,然后用装饰器返回的新函数覆盖原函数。例如,@display_time 等价于以下代码:

prime_nums = display_time(prime_nums)

二、装饰器的高级用法

1. 支持任意参数的装饰器

在实际开发中,被装饰的函数可能需要接收参数。因此,装饰器需要支持任意数量的位置参数和关键字参数。通过使用 *args**kwargs,可以实现这一点:

import timedef display_time(func):"""支持任意参数的时间统计装饰器"""def wrapper(*args, **kwargs):t1 = time.time()result = func(*args, **kwargs)  # 将参数传递给原函数t2 = time.time()print(f"函数执行时间: {t2 - t1} 秒")return result  # 返回原函数的返回值return wrapper@display_time
def add(a, b):return a + badd(3, 5)  # 输出:函数执行时间: 0.0 秒,返回值:8

2. 装饰器的返回值处理

如果被装饰的函数有返回值,装饰器需要正确处理并返回。例如:

def logger(func):def wrapper(*args, **kwargs):print(f"开始执行函数 {func.__name__},参数: {args}, {kwargs}")result = func(*args, **kwargs)print(f"函数 {func.__name__} 执行完毕,返回值: {result}")return resultreturn wrapper@logger
def multiply(a, b):return a * bmultiply(2, 3)  # 输出:开始执行函数 multiply,参数: (2, 3), {},返回值:6
multiply(a=2, b=3)  # 输出:开始执行函数 multiply,参数: (), {'a': 2, 'b': 3},返回值:6
multiply(2, b=3)  # 输出:开始执行函数 multiply,参数: (2,), {'b': 3},返回值:6

需要注意的是,关键字参数必须跟在所有位置参数之后,否则会报错。

@浙大疏锦行

相关文章:

  • 低空经济发展现状与前景
  • 使用lvm进行磁盘分区
  • 致敬经典 << KR C >> 之打印输入单词水平直方图和以每行一个单词打印输入 (练习1-12和练习1-13)
  • 基于Spring Boot和Vue的在线考试系统架构设计与实现(源码+论文+部署讲解等)
  • DeerFlow试用
  • 基于单片机的防盗报警器设计与实现
  • RT Thread FinSH(msh)调度逻辑
  • 计算机网络体系结构深度解析:从理论到实践的全面梳理
  • UE中的各种旋转
  • 视频下载器 2.3.9 | 自动识别并下载网页视频,界面简洁无广告带私密空间
  • AIStarter Windows 版本迎来重磅更新!模型插件工作流上线,支持 Ollama / ComfyUI 等多平台本地部署模型统一管理
  • c/c++的opencv的轮廓匹配初识
  • 使用 CodeBuddy 开发一款富交互的屏幕录制与注释分享工具开发纪实
  • A级、B级弱电机房数据中心建设运营汇报方案
  • 学习笔记:黑马程序员JavaWeb开发教程(2025.4.6)
  • 如何防止SQL注入攻击?
  • 使用ts-node搭建typescript运行环境
  • 现货黄金跌破 3160 美元,市场行情剧烈波动​
  • Node.js 实战三:Token 认证、Session 管理与中间件设计实战
  • 高并发内存池|定长内存池的设计
  • 专利申请全球领先!去年我国卫星导航与位置服务产值超5700亿元
  • 贞丰古城:新垣旧梦间的商脉与烟火
  • 四川内江警方通报一起持刀伤人致死案:因车辆停放引起,嫌犯被抓获
  • 今年有望投产里程已近3000公里,高铁冲刺谁在“狂飙”?
  • 秘鲁总统任命前司法部长阿拉纳为新总理
  • 夜读丨读《汉书》一得