深入解析:Day 30 函数专题2 装饰器

news/2026/1/17 9:09:49/文章来源:https://www.cnblogs.com/ljbguanli/p/19495108

深入解析:Day 30 函数专题2 装饰器

一、知识点

装饰器是 Python 中实用的高阶函数特性,核心作用是:不修改原函数代码、不改变原函数调用方式的前提下,给函数增加额外功能。

1. 为什么需要装饰器

若多个函数需要添加同一类通用功能(如计时、日志),不用装饰器会导致重复代码(每个函数都要写一遍功能逻辑);装饰器可将通用功能抽离出来,一次定义、多处复用,原函数无需任何改动。

2. 装饰器的核心结构

装饰器本质是 “接收函数作为参数,返回新函数” 的高阶函数,核心分三层逻辑:

  1. 装饰器函数:接收被装饰的原函数作为参数;
  2. 嵌套的 wrapper(包装)函数:核心层,负责实现额外功能(如计时、日志),同时调用原函数,通过 * args/**kwargs 兼容原函数的任意参数,且保留原函数的返回值;
  3. 返回 wrapper 函数:用新的包装函数替换原函数,@装饰器名是简化写法(语法糖),等价于 “原函数 = 装饰器名 (原函数)”。

3. 核心执行流程(以计时装饰器为例)

调用装饰后的函数→实际执行的是 wrapper 函数→wrapper 先执行额外功能(如计时开始)→调用原函数执行核心逻辑→原函数执行完毕后,wrapper 再执行剩余额外功能(如计算并打印耗时)→最后返回原函数的返回值,保证原函数功能不受影响。

4. 关键细节

  1. *args/**kwargs:确保装饰器能适配有参数、无参数、多参数等任意形式的原函数,提升通用性;
  2. functools.wraps:可选优化,用于保留原函数的名称、注释等身份信息,避免装饰后函数 “身份” 变成 wrapper。

5. 常见应用场景

除了计时、日志,还可用于权限校验(如接口登录检查)、缓存(避免重复计算)、异常捕获(统一处理函数异常)、性能监控(统计调用次数 / 耗时)等。

核心总结

装饰器就像给函数 “穿外套”:外套(wrapper)负责添加额外功能,里面的原函数本身不变,调用方式也和原来一样,却能多出来外套的功能。

二、普通函数与装饰器函数对比

1. 普通的函数

下面这个函数实现的是计算2到9999的所有质数(在大于 1 的自然数中,除了 1 和它自身外,不能被其他自然数整除的数),并且打印找到这些数需要的时间

  1. 1. 定义一个判断是否为质数
  2. 2. 定义一个函数,循环2到9999的数,通过判断质数函数来筛选每个数
  3. 3. 在函数中通过time模块进行记时

会发现,这个time模块让整个代码逻辑很混乱,因为函数的主体是找质数,time模块是找质数的时间,如果可以time模块放在函数外,这样逻辑才清晰。

import time
def is_prime(num):if num < 2:return Falseelif num == 2:return Trueelse:for i in range(2, num):if num % i == 0:return Falsereturn True
def 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()

2. 装饰器函数

import time
# 定义一个装饰器
def display_time(func):def wrapper(): # 定义一个内部函数,在装饰器中wrapper函数是一个常用的函数名,并非强制,约定俗成的start_time = time.time()func()  # 直接调用原函数(无参数),这里的func()是指装饰器需要修饰的函数,在这里是prime_nums()end_time = time.time()print(f"执行时间: {end_time - start_time} 秒")return wrapper # return wrapper是返回函数对象,如果是return wrapper()则是立即执行wrapper函数
# 继续定义判断质数的函数
def is_prime(num):"""判断一个数是否为素数"""if num < 2:return Falseelif num == 2:return Trueelse:for i in range(2, num):if num % i == 0:return Falsereturn True
# 装饰器的标准写法
@display_time
def prime_nums(): # 这2行是一个整体"""找出2到10000之间的所有素数并打印"""for i in range(2, 10000):if is_prime(i):print(i)
prime_nums()
# 执行时间每次都会变,但是变动不大,一般计算稳定的执行时间我们都是重复1000遍,然后取平均

装饰器的执行流程为:

  1. 定义装饰器函数 display_time:它接收一个函数 func 作为参数,并返回 wrapper 函数。
  2. 定义被装饰函数 prime_nums:此时 prime_nums 是一个普通函数对象。
  3. 应用装饰器:Python 自动将 prime_nums 作为参数传递给 display_time,即执行 display_time (prime_nums)。
  4. 替换原函数:display_time 返回 wrapper 函数,Python 用这个新函数覆盖了原来的 prime_nums。

也就是说装饰后,原函数名指向 wrapper,而非原始函数。

当你调用 prime_nums () 时,实际上执行的是 wrapper (),它会:

  1. 记录开始时间
  2. 调用 func ()(即原函数)
  3. 记录结束时间并打印耗时

这种等价的设计,会让初学者搞不懂为什么突然可以采取这种优雅的写法,类似的写法还有很多,在 python 中叫做语法糖:通过规范的写法来让代码更加优美和简洁,比如列表推导式也是,我们在后面再提。

你可以把 @理解为语法糖操作,实际上并非是 @装饰器,而是 @装饰器 + 下一行的代码 二者是一个整体。

3. 进一步拓展装饰器实现复用

可以看到,上述这个写法的时候,prime_nums()没有传入参数,如果函数有参数,那么必须给外部函数传入参数,也就是需要给外部的装饰器函数传入参数。

那么装饰器函数是需要复用的,不同的内部函数传入的参数不同,那就需要装饰器可以传入可变参数来维持这个特性。这就是说到了我们昨天的可变参数。

装饰器函数返回的是wrapper函数,所以,在调用装饰器函数的时候,返回的还是wrapper函数,而不是被修饰的函数。他是被修饰函数的外层函数,参数要大于等于被修饰函数的参数。

import time
def 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 + b
add(3, 5)  # 正常接收参数并计算

三、作业

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 * b
multiply(2, 3)
开始执行函数multiply, 参数:(2, 3), {}
函数 multiply 执行完毕. 返回值:6

勇闯python的第30天@浙大疏锦行

一些碎碎念念:

      转眼间,跟着疏老师系统学习Python已整整30天。回首这段时光,收获满满,心中满是感激——由衷感谢您提供了如此优质的学习机会,让我得以深入探索这门语言的魅力,您辛苦了!

      本科期间,我并非计算机专业,但曾接触过SPSS、R语言等相关知识,当时便对数据与编程的世界充满好奇。而这次系统学习Python,更让我感受到了不一样的惊喜:从未想过,一门编程语言竟能将数字的严谨与视觉的美感完美融合,绘制出如此多优美的图案。这种“用代码创造美”的体验,让我对编程的兴趣愈发浓厚,也彻底打破了我对“编程枯燥”的刻板印象。 经过这30天的系统沉淀,我不仅加深了对Python的理解,更找到了持续探索的动力。

       计算机语言的世界奥秘无穷,我早已满怀期待,渴望在接下来的学习中解锁更多技能,进一步探索其中的精彩。未来,我也会带着这份热爱,在编程的道路上稳步前行,不负这段宝贵的学习时光。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1172767.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

444KB 封神!DisplayAffinit,窗口防截图隐私守护神

444KB 封神&#xff01;DisplayAffinit&#xff0c;窗口防截图隐私守护神 谁懂啊&#xff01;办公时聊个私密内容、处理敏感文件&#xff0c;总担心窗口被别人随手截图泄露&#xff0c;找遍工具不是体积大就是操作复杂&#xff0c;真心难顶。 下载地址&#xff1a;https://pa…

2025年广州去甲醛公司推荐榜:广州市可达环保科技有限公司,除甲醛/测甲醛/除甲醛公司/祛甲醛/除甲醛品牌/治理甲醛/甲醛检测公司精选 - 品牌推荐官

高温高湿的岭南气候与密集的装修需求叠加,广州已成为全国除甲醛市场增长最快的地区之一,专业除甲醛服务从选择变为刚需。 在广州这座气候湿热、装修需求旺盛的城市,室内空气质量问题日益受到关注。随着国家《室内空…

2026年GEO服务商深度评测:技术实力与效果转化双维解析 - 品牌推荐

2026年,数字营销已全面迈入全域智能运营新阶段,生成式引擎优化(GEO)成为企业获取高质量商业线索不可或缺的核心支柱。本次评测聚焦市场主流服务商,基于技术架构、算法效率、服务覆盖、实战成效及客户口碑五大核心…

Python在毕业设计中的核心作用与实战难点解析

摘要Python凭借简洁语法、丰富生态及跨场景适配能力&#xff0c;成为计算机、软件工程、大数据等专业毕业设计的首选语言之一。本文梳理Python在毕设中的核心应用价值&#xff0c;拆解开发过程中的核心难点及应对思路&#xff0c;为毕业生提供实操参考。关键词&#xff1a;Pyth…

springboot乡镇医院挂号预约小程序设计实现

乡镇医院挂号预约小程序的设计背景乡镇地区医疗资源相对匮乏&#xff0c;患者就医常面临排队时间长、挂号难等问题。传统线下挂号方式效率低下&#xff0c;无法满足农村居民日益增长的医疗需求。移动互联网技术的普及为优化乡镇医疗流程提供了可能&#xff0c;通过小程序实现线…

2026年二手工业电炉/退火炉/变压器/冷却塔/中频炉设备采购指南:唐山市丰润区诚信电炉维修部,设备回收改制一站式服务 - 品牌推荐官

在工业生产领域,二手工业电炉及相关设备的需求日益增长,尤其在冶金、化工等行业中,设备的高效利用与成本控制成为企业关注的重点。唐山市丰润区诚信电炉维修部凭借多年行业经验,已成为华北地区二手工业电炉回收、改…

2026年GEO服务商深度评测:技术实力与效果转化的双维解析 - 品牌推荐

2026年,数字营销已全面迈入全域智能运营的新阶段,生成式引擎优化(GEO)成为企业获取高质量商业线索不可或缺的核心支柱。本次评测聚焦市场主流服务商,依据技术架构、算法效率、服务覆盖、实战成效及客户口碑五大核…

基于ssm的中小学生个性化阅读平台的设计与实现

背景与现状分析当前中小学生阅读普遍存在同质化、应试化倾向&#xff0c;传统推荐方式难以满足个性化需求。教育信息化2.0行动计划强调技术赋能因材施教&#xff0c;而SSM框架&#xff08;SpringSpringMVCMyBatis&#xff09;因其轻量级、分层架构优势&#xff0c;适合快速开发…

2026年GEO优化服务选购看什么?这份权威评测与口碑排名说清楚了 - 品牌推荐

2026年,生成式引擎优化已成为企业获取高质量商机与构建品牌智能认知的核心战略。本评测聚焦主流GEO服务商,从技术架构、行业适配、实战成效及服务模式等多维度构建评估模型,通过真实场景测试与跨行业案例归因,客观…

毕设指南【一键到位】

前言 毕业设计是计算机专业学生大学四年的综合检验&#xff0c;是将理论知识转化为实践能力的关键环节。面对从选题、开发到论文、答辩的全过程&#xff0c;很多同学常感迷茫与压力。 本指南基于实际指导经验&#xff0c;聚焦毕设核心要点&#xff0c;提供从技术选型、开发实…

毕设指南【一键到位】

前言 毕业设计是计算机专业学生大学四年的综合检验&#xff0c;是将理论知识转化为实践能力的关键环节。面对从选题、开发到论文、答辩的全过程&#xff0c;很多同学常感迷茫与压力。 本指南基于实际指导经验&#xff0c;聚焦毕设核心要点&#xff0c;提供从技术选型、开发实…

小挖机定制厂家哪家性价比高? - 工业品牌热点

一、基础认知篇 问题1:市场上的小挖机定制厂家那么多,怎么判断哪家是靠谱的? 判断靠谱的小挖机定制厂家,核心要看场景适配力、品质把控力、服务响应力三个维度,而山东华科机械有限公司在这三点上的表现尤为突出。…

springboot视频点播微信小程序设计开发实现

背景分析视频点播&#xff08;VOD&#xff09;系统在移动互联网时代需求激增&#xff0c;结合微信小程序的高普及率与SpringBoot的高效开发能力&#xff0c;设计开发此类系统具有多重背景意义&#xff1a;技术融合趋势&#xff1a;微信小程序提供轻量化入口&#xff0c;SpringB…

springboot视频点播微信小程序设计开发实现

背景分析视频点播&#xff08;VOD&#xff09;系统在移动互联网时代需求激增&#xff0c;结合微信小程序的高普及率与SpringBoot的高效开发能力&#xff0c;设计开发此类系统具有多重背景意义&#xff1a;技术融合趋势&#xff1a;微信小程序提供轻量化入口&#xff0c;SpringB…

2026年GEO优化服务商推荐:2026年度权威评测与真实用户评价排名报告 - 品牌推荐

随着生成式引擎彻底重塑用户获取信息的路径,GEO优化已从营销领域的创新尝试,演变为决定品牌未来数年市场地位的关键战役。行业数据显示,高达84%的领先企业已将GEO纳入年度核心预算,市场规模的快速增长也带来了选择…

GESP认证C++编程真题解析 | B4263 [GESP202503 四级] 荒地开垦

欢迎大家订阅我的CSDN专栏:算法题解:C++与Python实现! 本专栏旨在帮助大家从基础到进阶 ,逐步提升编程能力,助力信息学竞赛备战! 专栏特色 1.经典算法练习:根据信息学竞赛大纲,精心挑选经典算法题目,提供清晰…

GESP认证C++编程真题解析 | B4262 [GESP202503 三级] 词频统计

欢迎大家订阅我的CSDN专栏:算法题解:C++与Python实现! 本专栏旨在帮助大家从基础到进阶 ,逐步提升编程能力,助力信息学竞赛备战! 专栏特色 1.经典算法练习:根据信息学竞赛大纲,精心挑选经典算法题目,提供清晰…

springboot微信小程序民宿预订管理系统设计与实现

背景与意义市场需求驱动 随着旅游业的快速发展和共享经济的兴起&#xff0c;民宿行业呈现爆发式增长。传统民宿预订方式依赖电话或第三方平台&#xff0c;存在信息不透明、沟通效率低、佣金高等问题。微信小程序凭借其免安装、易传播的特性&#xff0c;成为解决这一痛点的理想载…

面试题_ZH

面试题_ZH以下是这些面试题的简短回答: 一、后台一面题 1. SpringBoot加载过程 启动类触发 SpringApplication.run() ,依次完成:初始化环境→加载配置→创建上下文→扫描Bean→自动装配→启动嵌入式容器。 2. 循环依…

2026年市场上口碑好的打包扣供应商有哪些,市面上打包扣源头厂家甄选实力品牌 - 品牌推荐师

在工业包装与物流运输领域,打包扣作为连接打包带、确保货物捆扎牢固的关键部件,其质量直接关系到运输安全与成本效率。随着制造业与物流业的持续升级,市场对镀锌打包扣等产品的耐腐蚀性、强度及可靠性提出了更高要求…