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

Day 27 函数专题2 装饰器

昨天我们接触到了函数大部分的功能,然后在你日常ctrl点进某个复杂的项目,发现函数上方有一个@xxx,它就是装饰器

装饰器本质上是一个 Python 函数,它可以让其他函数或方法在不需要做任何代码修改的前提下增加额外功能。

--本质是如果让一个函数具备太多功能,那么他看起来就会比较乱,可读性比较差,如果把其中一部分相同甚至可以复用的功能用一个新的函数来调用,然后让2个函数同时实现,就会做到进一步封装了函数的一些用法,做到dry原则(don't repeat yourself),使函数更加具有可读性

所以装饰器本身就是函数中调用其他函数,实现先拆分函数,再合并函数的功能。

普通的函数

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

在函数中通过time模块进行记时

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

import timedef is_prime(num): if num < 2:return Falsefor i in range(2,int(num**0.5) + 1):if num % i == 0:return Falsereturn Truedef prime_nums():begin_time = time.time()for i in range(2,1000000):is_prime(i) # 就不输出了,避免太多end_time = time.time()print(f"程序运行时间为{end_time - begin_time}秒")prime_nums()

运行结果: 程序运行时间为5.0821802616119385秒

装饰器函数

装饰器函数的参数是另一个函数,返回值也是一个函数;可以参考下方代码,看下优化在哪里。

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 Falsefor i in range(2,int(num**0.5) + 1):if num % i == 0:return Falsereturn True@display_time #下面这个函数就是display_time的参数(fun)
def prime_nums():for i in range(2,1000000):is_prime(i) # 就不输出了,避免太多prime_nums()

运行结果:执行时间: 4.53002142906189 秒

逻辑上还是一样的,只不过这个把非重点函数的功能装饰起来了,使得我们看到的代码更加清晰明了。

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

就是说一个装饰器可以被当作多个函数来用,其实就是传参数的问题,默认参数,或者一个、两个参数。

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

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

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

今日作业

# 作业答案def logger(func):def wrapper(*args, **kwargs):  # 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 函数,观察日志输出

 总结

装饰器是 Python 里的语法糖,本质是高阶函数,能在不修改原函数代码和调用方式的前提下,为函数添加额外功能。

它接收一个函数作为参数,返回一个新函数。新函数会包裹原函数,在执行原函数前后添加新逻辑,比如日志记录、性能测试等。使用时,通过 `@` 符号将装饰器应用到目标函数上,提高代码复用性和可维护性,让代码更简洁优雅。

相关文章:

  • 高可用消息队列实战:AWS SQS 在分布式系统中的核心解决方案
  • Core Web Vitals 全链路优化:从浏览器引擎到网络协议深度调优
  • Java + 鸿蒙双引擎:ZKmall开源商城如何定义下一代B2C商城技术标准?
  • 【Linux网络】数据链路层
  • 在服务器上安装AlphaFold2遇到的问题(2)
  • #跟着若城学鸿蒙# web篇-获取定位
  • 质量管理工程师面试总结
  • React文件上传组件封装全攻略
  • React Flow 节点属性详解:类型、样式与自定义技巧
  • python打卡day27
  • 组件导航 (HMRouter)+flutter项目搭建-混合开发+分栏效果
  • Jenkins的流水线执行shell脚本执行jar命令后项目未启动未输出日志问题处理
  • 变量赋值和数据类型
  • 线程池(ThreadPoolExecutor)实现原理和源码细节是Java高并发面试和实战开发的重点
  • 用GPU训练模型的那些事:PyTorch 多卡训练实战
  • moveit2报错!
  • MongoTemplate 基础使用帮助手册
  • C#中UI线程的切换与后台线程的使用
  • neo4j框架:ubuntu系统中neo4j安装与使用教程
  • 小白用AI 完整的deepseek使用指南
  • 广西壮族自治区党委副书记、自治区政府主席蓝天立接受审查调查
  • 选址江南制造总局旧址,上海工业博物馆建设有新进展
  • 科普|男性这个器官晚到岗,可能影响生育能力
  • 上海静安将发放七轮文旅消费券,住宿券最高满800元减250元
  • 玉渊谭天丨卢拉谈美国降低对华关税:中国的行动捍卫了主权
  • 西班牙政府排除因国家电网遭攻击导致大停电的可能