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

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

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

@浙大疏锦行

相关文章:

day27 python 装饰器

目录 一、装饰器的基本概念 示例&#xff1a;用装饰器优化质数查找函数 二、装饰器的高级用法 1. 支持任意参数的装饰器 2. 装饰器的返回值处理 在 Python 编程中&#xff0c;装饰器是一个非常强大的功能&#xff0c;它可以让其他函数或方法在不需要做任何代码修改的前提下…...

Visual Studio2022跨平台Avalonia开发搭建

由于我已经下载并安装了 VS2022版本&#xff0c;这里就跳过不做阐述。 1.安装 Visual Studio 2022 安装时工作负荷Tab页勾选 ‌“.NET 桌面开发”‌ 和“Visual Studio扩展开发”‌ &#xff0c;这里由于不是用的微软的MAUI&#xff0c;所以不用选择其他的来支持跨平台开发&a…...

css iconfont图标样式修改,js 点击后更改样式

背景&#xff1a; 在vue项目中&#xff0c;通过点击/鼠标覆盖&#xff0c;更改选中元素的样式&#xff0c;可以通过js逻辑&#xff0c;也可以根据css样式修改。包括以下内容&#xff1a;iconfont图标的引入以及使用&#xff0c;iconfont图标样式修改【导入文件是纯白&#xff0…...

开源项目实战学习之YOLO11:12.4 ultralytics-models-sam-memory_attention.py源码分析

👉 点击关注不迷路 👉 点击关注不迷路 👉 另外,前些天发现了一个巨牛的AI人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。感兴趣的可以点击相关跳转链接。 点击跳转到网站。 ultralytics-models-sam 1.sam-modules-memory_attention.pyblocks.py: 定义模…...

【沉浸式求职学习day42】【算法题:滑动窗口】

沉浸式求职学习 长度最小的子数组水果成篮 关于算法题&#xff1a;滑动窗口的几个题目 长度最小的子数组 给定一个含有 n 个正整数的数组和一个正整数 s &#xff0c;找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组&#xff0c;并返回其长度。如果不存在符合条件的子数组…...

LIIGO ❤️ RUST 12 YEARS

LIIGO &#x1f496; RUST 12 YEARS 今天是RUST语言1.0发布十周年纪念日。十年前的今天&#xff0c;2015年的今天&#xff0c;Rust 1.0 正式发行。这是值得全球Rust支持者隆重纪念的日子。我借此机会衷心感谢Rust语言创始人Graydon Hoare&#xff0c;Mozilla公司&#xff0c;以…...

Linux基础开发工具二(gcc/g++,自动化构建makefile)

3. 编译器gcc/g 3.1 背景知识 1. 预处理&#xff08;进行宏替换/去注释/条件编译/头文件展开等) 2. 编译&#xff08;生成汇编) 3. 汇编&#xff08;生成机器可识别代码&#xff09; 4. 连接&#xff08;生成可执行文件或库文件) 3.2 gcc编译选项 格式 &#xff1a; gcc …...

Linux zip、unzip 压缩和解压

zip 命令用于压缩文件&#xff0c;压缩后的文件后缀名为 .zip 。 对应的解压命令是 unzip 。 测试用的目录结构如下&#xff0c; userzn:~/test$ tree . ├── folder1 │ ├── folder111 │ │ └── file1.txt │ └── main1.c ├── folder2 │ ├── …...

muduo库TcpConnection模块详解——C++

muduo库中的TcpConnection模块详解 TcpConnection是muduo库中处理TCP连接的核心模块&#xff0c;负责管理单个TCP连接的生命周期、数据读写、状态转换以及事件回调。每个TCP连接对应一个TcpConnection对象&#xff0c;其设计体现了高性能、线程安全和灵活回调的特点。 一、核心…...

Node.js 源码架构详解

Node.js 的源码是一个庞大且复杂的项目&#xff0c;它主要由 C 和 JavaScript 构成。要完全理解每一部分需要大量的时间和精力。我会给你一个高层次的概述&#xff0c;并指出一些关键的目录和组件&#xff0c;帮助你开始探索。 Node.js 的核心架构 Node.js 的核心可以概括为以…...

全局异常处理:如何优雅地统一管理业务异常

在软件开发中&#xff0c;异常处理是保证系统健壮性的重要环节。一个良好的异常处理机制不仅能提高代码的可维护性&#xff0c;还能为使用者提供清晰的错误反馈。本文将介绍如何通过全局异常处理和业务异常统一处理来编写更加优雅的代码。 一、传统异常处理的痛点 1.1 典型问…...

分布式锁: Redis和ZooKeeper两种分布式锁对比

在分布式系统中&#xff0c;分布式锁是协调多节点共享资源访问的核心机制。Redis 和 ZooKeeper 是两种常用的分布式锁实现方案&#xff0c;但两者的设计理念、适用场景和优缺点存在显著差异。本文将从 一致性模型、性能、可靠性、实现原理 等维度进行对比&#xff0c;并提供技术…...

动态规划-LCR 166.珠宝的最大价值-力扣(LeetCode)

一、题目解析 frame二维矩阵中每个值代表珠宝的价值&#xff0c;现在从左上角开始拿珠宝&#xff0c;只能向右或向下拿珠宝&#xff0c;到达右下角时停止拿珠宝&#xff0c;要求拿的珠宝价值最大。 二、算法解析 1.状态表示 我们想要知道的是到达[i,j]为位置时的最大价值&am…...

JDBC实现模糊、动态与分页查询的详解

文章目录 一. 模糊查询1. Mysql的写法2. JDBC的实现 二. 动态条件查询1. 创建生成动态条件查询sql的方法2. 完整的动态条件查询类以及测试类 三. 分页查询1. 什么是分页查询&#xff1f;2. 分页查询的分类3. MySQL的实现4. JDBC实现4.1. 创建page页4.2. 分页的实现 本章来讲一下…...

域环境信息收集技术详解:从基础命令到实战应用

引言 在企业网络环境中&#xff0c;Active Directory (AD)域服务是微软提供的集中式目录服务&#xff0c;用于管理网络中的用户、计算机和其他资源。对于信息安全专业人员来说&#xff0c;熟练掌握域环境信息收集技术至关重要&#xff0c;无论是进行渗透测试、安全评估还是日常…...

nodejs特性解读

单线程和事件驱动架构 参考 程序员dd-事件驱动架构 it-老齐-事件驱动架构 总结...

【C++ Qt】布局管理器

每日激励&#xff1a;“不设限和自我肯定的心态&#xff1a;I can do all things。 — Stephen Curry” &#x1f914;绪论​&#xff1a; 在Qt开发中&#xff0c;界面布局的合理设计是提升用户体验的关键。早期&#xff0c;开发者常采用绝对定位的方式摆放控件&#xff0c;即通…...

vscode用python开发maya联动调试设置

如何在VScode里编写Maya Python脚本_哔哩哔哩_bilibili1 包括1&#xff0c;maya的python全面在vscode支持&#xff0c;2&#xff0c;通过mayacode发送到maya&#xff0c;3同步调试 import maya.cmds as cmds 1、让 maya.cmds编译通过 下载Autodesk_Maya_2018_6_Update_DEVK…...

SLAM定位常用地图对比示例

序号 地图类型 概述 1 格栅地图 将现实环境栅格化,每一个栅格用 0 和 1 分别表示空闲和占据状态,初始化为未知状态 0.5 2 特征地图 以点、线、面等几何特征来描绘周围环境,将采集的信息进行筛选和提取得到关键几何特征 3 拓扑地图 将重要部分抽象为地图,使用简单的图形表示…...

Ubnutu ADB 无法识别设备的解决方法

1. 正确安装adb 下载地址 2. 检查 Linux 是否识别设备 lsusb通过上述指令&#xff0c;分别查询插入、断开设备的usb设备表&#xff0c;如下所示&#xff1a; # 插入设备 adbc:~$ lsusb Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 001 Device 011:…...

前端-HTML元素

目录 HTML标签是什么&#xff1f; 什么是HTML元素&#xff1f; HTML元素有哪些分类方法&#xff1f; 什么是HTML头部元素 更换路径 注&#xff1a;本文以leetbook为基础 HTML标签是什么&#xff1f; HTML标签是HTML语言中最基本单位和重要组成部分 虽然它不区分大小写&a…...

dagster的etl实现

本文展示了如何使用Dagster框架实现一个动态ETL&#xff08;Extract, Transform, Load&#xff09;流程。通过定义多个操作&#xff08;op&#xff09;&#xff0c;包括生成动态任务、处理单个任务、收集结果和汇总结果&#xff0c;构建了一个动态任务处理流程。generate_tasks…...

python的漫画网站管理系统

目录 技术栈介绍具体实现截图![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/0ed2084038144499a162b3fb731a5f37.png)![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/a76a091066f74a80bf7ac1be489ae8a8.png)系统设计研究方法&#xff1a;设计步骤设计流程核…...

源码安装gperftools工具

源码安装gperftools工具 下载gperftools源码 https://github.com/gperftools/gperftools/releases/download/gperftools-2.16/gperftools-2.16.tar.gz 注&#xff1a;需要下载github上release版本&#xff0c;如果直接下载master分支上源码&#xff0c;将可能出现各种编译报错…...

QMK 宏(Macros)功能详解(实战部分)

QMK 宏(Macros)功能详解(实战部分) 一、宏的基本概念与作用 宏(Macros)是 QMK 固件中一项强大的功能,它允许您在按下单个按键时执行多个按键操作。通过宏,您可以: 输入常用短语或文本执行复杂的按键组合自动化重复性操作触发系统功能或快捷键🔔 安全提示:虽然可以…...

前端脚手架开发指南:提高开发效率的核心操作

前端脚手架通过自动化的方式可以提高开发效率并减少重复工作&#xff0c;而最强大的脚手架并不是现成的那些工具而是属于你自己团队量身定制的脚手架&#xff01;本篇文章将带你了解脚手架开发的基本技巧&#xff0c;帮助你掌握如何构建适合自己需求的工具&#xff0c;并带着你…...

搜索引擎工作原理|倒排索引|query改写|CTR点击率预估|爬虫

写在前面 使用搜索引擎是我们经常做的事情&#xff0c;搜索引擎的实现原理。 什么是搜索引擎 搜索引擎是一种在线搜索工具&#xff0c;当用户在搜索框输入关键词时&#xff0c;搜索引擎就会将与该关键词相关的内容展示给用户。比较大型的搜索引擎有谷歌&#xff0c;百度&…...

Python实例题:Python自动工资条

目录 Python实例题 题目 python-automatic-payroll-slipPython 自动生成工资条脚本 代码解释 加载文件&#xff1a; 获取表头&#xff1a; 写入表头&#xff1a; 生成工资条&#xff1a; 保存文件&#xff1a; 运行思路 注意事项 Python实例题 题目 Python自动工资…...

Function Calling万字实战指南:打造高智能数据分析Agent平台

个人主页&#xff1a;Guiat 归属专栏&#xff1a;科学技术变革创新 文章目录 1. Function Calling&#xff1a;智能交互的新范式1.1 Function Calling 技术概述1.2 核心优势分析 2. 数据分析Agent平台架构设计2.1 系统架构概览2.2 核心组件解析2.2.1 函数注册中心2.2.2 Agent控…...

spark MySQL数据库配置

Spark 连接 MySQL 数据库的配置 要让 Spark 与 MySQL 数据库实现连接&#xff0c;需要进行以下配置步骤。下面为你提供详细的操作指南和示例代码&#xff1a; 1. 添加 MySQL JDBC 驱动依赖 你得把 MySQL 的 JDBC 驱动添加到 Spark 的类路径中。可以通过以下两种方式来完成&a…...