例解什么是Python装饰器

Python中的装饰器一直是一个比较难理解的概念,我自己理解的就是用一个函数去修改另一个函数,主要是为另一个函数添加计时等功能,而且不用改变另一个函数,这样就大大减少了另一个函数的维护成本。

这个装饰器,英文名就是decorator,相关于把一个写好的程序添加一些新的功能,让这个程序变成多功能的。装饰器还可以传递参数,但如果要加参数就要多一层。

首先,我们看一个样例[1],有一个计算数字平方和的函数,我们添加一个装饰器elasped,来为它增加计算函数运行时间的功能。

一、不用@添加装饰器的写法

# 对目标函数进行elapsed装饰器函数的调用
# 返回一个装饰后的名字还是叫power_sum的函数
import time
def elapsed(target):
    "统计函数执行的耗时:"
    def decorated(*args,**kwargs):
        start = time.time()
        r = target(*args,**kwargs)
          
        end = time.time()
        print("函数执行耗时:", round(end - start, 2))
        return r
    return decorated

def power_sum(n):
    "计算并返回1到n之间每个数的平方的和"
    total = 0
    for i in range(1,n+1):
        total += i**2
    return total
if __name__ == "__main__":
    power_sum = elapsed(power_sum) # 相当于用装饰器函数elapsed调用了power_sum函数
    print(power_sum(1000000))

二、使用@加装饰器的调用方法

# 对目标函数进行elapsed装饰器函数的调用
# 返回一个装饰后的名字还是叫power_sum的函数
import time
def elapsed(target):
    "统计函数执行的耗时:"
    def decorated(*args,**kwargs):
        start = time.time()
        r = target(*args,**kwargs)
          
        end = time.time()
        print("函数执行耗时:", round(end - start, 2))
        return r
    return decorated

@elapsed   # 相当于用装饰器函数elapsed调用了power_sum函数相当于这行代码:power_sum = elapsed(power_sum)
def power_sum(n):
    "计算并返回1到n之间每个数的平方的和"
    total = 0
    for i in range(1,n+1):
        total += i**2
    return total
if __name__ == "__main__":
    print(power_sum(1000000))

调用结果:

三、为装饰器加上参数的方法

现在为装饰器加上参数,把函数执行耗时的时间加上可以控制保留小数位数的参数precision,结果如下:

# 对目标函数进行elapsed装饰器函数的调用
# 返回一个装饰后的名字还是叫power_sum的函数
import time
def elapsed_precision(precision):
    def elapsed(target):
        "统计函数执行的耗时:"
        def decorated(*args,**kwargs):
            start = time.time()
            r = target(*args,**kwargs)
              
            end = time.time()
            print("函数执行耗时:", round(end - start, precision))
            return r
        return decorated
    return elapsed

#不写就没有装饰器效果,写了相当于这一句:power_sum = elapsed(power_sum) 也就是power_sum被装饰后又重新命名为power_sum函数
@elapsed_precision(3)# 这里的3就是装饰器的参数。
def power_sum(n):
    "计算并返回1到n之间每个数的平方的和"
    total = 0
    for i in range(1,n+1):
        total += i**2
    return total
if __name__ == "__main__":
    print(power_sum(10000000))

由上述代码可见,我们加装饰器后,原来的函数没有变化,我们只是通过装饰器给power_sum函数添加计时功能,传递了一个保留小数位数的参数precision。

四、学后反思

1. 装饰器是python学习中一个比较难理解的概念,因为我们一直把函数的参数局限为字符、列表、元组、字典这些常用的数据结构,但是如果我们把函数看成一个对象,把一个函数作为另一函数(装饰器)的参数来调用就好理解了。
2. 装饰器可以使Python编写的代码更容易维护,同时也可以为函数增加更多的功能,是Python程序编写过程中一个重要的工具。
3. 在我学习Python的过程中,我一直对装饰器、多线程、异步这些概念模糊不清楚。虽然也有意去学习,但很多时候是一知半解,后来通过B站学习和个人的思考慢慢把这些概念理解弄通。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

休闲娱乐 - 挂耳咖啡

公司有一个小的茶歇间,平时去喝个咖啡、放松身心、锻炼下身体。咖啡机是现磨咖啡豆的,喝喝就习惯了。 而我旁边一位同事习惯每天早上来自己泡一杯挂耳咖啡,再配上牛奶,感觉挺高级的。 关于挂耳咖啡就查了一下资料,介绍…

怎样班群发成绩?

身为老师,定期发布学生成绩是项重要任务。在过去,这项任务需要手动操作,工作量大而且总是发错。不过诶,现在我们可以通过各种方式实现学生自助查询成绩,既提高了效率又不会发错! 就是需要制作一个查询系统。…

Python | 机器学习之PCA降维

​🌈个人主页:Sarapines Programmer🔥 系列专栏:《人工智能奇遇记》🔖少年有梦不应止于心动,更要付诸行动。 目录结构 1. 机器学习之PCA降维概念 1.1 机器学习 1.2 PCA降维 2. PCA降维 2.1 实验目的 2…

RT-Thread STM32F407 定时器

定时器简介 硬件定时器一般有 2 种工作模式,定时器模式和计数器模式。不管是工作在哪一种模式,实质都是通过内部计数器模块对脉冲信号进行计数。下面是定时器的一些重要概念。 计数器模式:对外部输入引脚的外部脉冲信号计数。 定时器模式&…

【项目】云备份系统基础功能实现

目录 一.项目介绍1.云备份认识2.服务端程序负责功能与功能模块划分3.客户端程序负责功能与功能模块划分4.开发环境 二.环境搭建1.gcc升级7.3版本2.安装jsoncpp库3.下载bundle数据压缩库4.下载httplib库 三.第三方库认识1.json(1)json认识(2)jsoncpp认识(3)json实现序列化(4)jso…

Centos7安装Redis

1.背景 2.步骤 1.安装gcc依赖 检查是否已安装gcc gcc -v 上图表示已安装,如果没有安装执行如下命令 [rootlocalhost local]# yum install -y gcc 2.下载并解压安装包 [rootlocalhost local]# wget http://download.redis.io/releases/redis-5.0.3.tar.gz [rootlocalhost lo…

001 opencv addWeighted

目录 一、环境 二、addWeighted函数 三、代码演示 一、环境 本文使用环境为: Windows10Python 3.9.17opencv-python 4.8.0.74 二、addWeighted函数 OpenCV中的cv.addWeighted函数是一个用于图像叠加的函数,它可以将两个具有相同尺寸和类型的图像按…

本地新建vs工程运行c++17std::varant

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么?二、使用步骤 1.引入库2.读入数据总结 前言 提示:这里可以添加本文要记录的大概内容: 例如:…

【C++】类和对象(5)--拷贝构造函数

目录 一 概念 二 拷贝构造函数特性 1. 重载形式 2. 参数原则 3 默认拷贝函数 三 拷贝构造函数的实现 一 概念 在创建对象时,可否创建一个与已存在对象一某一样的新对象呢? class Date { public:Date(int year 1900, int month 1, int day 1)/…

vscode的git 工具使用

vscode的git 工具使用 目录概述需求: 设计思路实现思路分析1.git 工具的使用2.提交代码3.查看历史提交代码 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy,skip hardness,make a be…

关于接口测试自动化的总结与思考!

序 近期看到阿里云性能测试 PTS 接口测试开启免费公测,本着以和大家交流如何实现高效的接口测试为出发点,本文包含了我在接口测试领域的一些方法和心得,希望大家一起讨论和分享,内容包括但不仅限于: 服务端接口测试介…

FPGA实现Avalon-MM接口通信

在Avalon总线协议(一)和Avalon总线协议(二)中大概了解Avalon总线的几种类型,目前比较常用到的就是Avalon-MM接口了,虽然在概念中有那么多的属性,但是具体使用起来还是非常简单的。 一、Avalon-…

【Mysql】关于数据库增删查改的一些在线OJ练习

🌈欢迎来到Python专栏 🙋🏾‍♀️作者介绍:前PLA队员 目前是一名普通本科大三的软件工程专业学生 🌏IP坐标:湖北武汉 🍉 目前技术栈:C/C、Linux系统编程、计算机网络、数据结构、Mys…

大数据-之LibrA数据库系统告警处理(ALM-12048 网络写包错误率超过阈值)

告警解释 系统每30秒周期性检测网络写包错误率,并把实际错误率和阈值(系统默认阈值0.5%)进行比较,当检测到网络写包错误率连续多次(默认值为5)超过阈值时产生该告警。 用户可通过“系统设置 > 阈值配置…

PLC和SCADA有什么区别?

让我们谈谈SCADA和HMI之间的区别。今天,我们将讨论它们的区别和相似之处,以及各自的用途。由于相似之处,通常会出现一些混淆。 现在让我们深入了解SCADA 。SCADA代表“监控和数据采集”。它们用于监视和控制大面积区域,通常是整个…

Vue3 使用教程

目录 一、创建vue3工程1. 使用vue-cli创建2.使用 vite 创建 二、setup使用三、ref函数四、reactive函数五、计算属性与监视属性5.1 computed函数5.2 watch函数5.3 watchEffect函数 六、自定义hook函数七、toRef函数八、shallowReactive 与 shallowRef九、readonly 与 shallowRe…

Vue23全局事件总线

Vue2&3全局事件总线 Vue2全局事件总线 功能:可以解决所有组件之间通信传数据的问题原理:通过一个共享对象,将所有组件全部绑定到对象上,即可通过这个对象实现组件与组件之间的传递数据,而这个共享对象叫做全局事件…

TSINGSEE青犀AI智能分析+视频监控工业园区周界安全防范方案

一、背景需求分析 在工业产业园、化工园或生产制造园区中,周界防范意义重大,对园区的安全起到重要的作用。常规的安防方式是采用人员巡查,人力投入成本大而且效率低。周界一旦被破坏或入侵,会影响园区人员和资产安全,…

【JUC】八、阻塞队列

文章目录 1、阻塞队列概述2、阻塞队列分类3、 阻塞队列的四组核心方法4、Demo 队列,先进先出,类似排队栈,先进后出,用于要优先处理最近发生的事件的场景 1、阻塞队列概述 阻塞队列,一个生产消费模式,当&a…

数组相关面试题--5.合并两个有序数组

5. 合并两个有序数组 88. 合并两个有序数组 - 力扣(LeetCode) 解题思路:1. 从后往前遍历数组,将nums1和nums2中的元素逐个比较将较大的元素往nums1末尾进行搬移2. 第一步结束后,nums2中可能会有数据没有搬移完,将nums…