提及闭包函数,不得不说【python装饰器】

news2025/7/11 2:22:01
什么是装饰器
1. python装饰器是用于拓展原来函数功能的一种函数,目的是在不改变原函数的情况下,给函数增加功能。
2. 装饰器是通过闭包实现,所以讲装饰器首先得知道什么是闭包。

 

图片

 

什么是闭包
 

一、什么是闭包

1. 一个定义在函数内部的函数,闭包可以让变量脱离了该函数的作用域也依然能被访问到
2. 定义一个嵌套函数,内函数内部使用外函数变量,让外函数将内函数当做参数返回,这样就组成了一个闭包


二、举个例子

def outer(x):    def inner():        y = x * 2        return y    return innerresult=outer(10)print(result())
 

三、执行过程分析

1. 调用外函数(outer),将参数赋值给x,此时x=10
2. 执行外函数(outer),内函数(inner)不会被执行
3. 执行到return语句此时返回内函数inner对象(不会被调用)
4. 此时外函数(outer)执行结束的时候发现内部函数会用到自己的临时变量
5. 此时外函数(outer)临时变量就不会释放,会绑定给内函数内函数(inner)继续使用
6. 此时result得到的结果就是inner引用(对象),调用result就等于执行内函数(inner)

图片

三、函数装饰器
一、原理
1. 闭包的特性
2. 函数可以被当做参数传递

二、举个例子

import timedef outer(fn):    def inner(x,y):        start_time = time.time()        result = fn(x,y)        end_time = time.time()        return result,end_time - start_time    print('第一次',inner)    return inner  @outerdef test01(x,y):    time.sleep(5)    return x+yprint('第二次',test01)result=test01(1,2)print(result)
 

三、执行过程分析

第一步:执行到@outer相当于把函数 test01 赋值给 outer函数的fn参数

第二步:执行outer函数,返回inner函数

1、outer函数内部嵌套了一个inner函数,利用闭包的原理inner函数可以直接使用outer函数fn的参数
2、在执行outer函数的时候,inner函数并未被执行,是直接返回inner函数给test01函数

3、此时的test01函数已经被outer增加功能后返回的inner函数替换掉了(第一次,第二次打印结果就是证据)

第三步:执行test01(1,2),此时相当于执行inner(1,2)函数参数直接传递给inner函数的x,y

内存地址变化
1. outer内存地址:`<function outer at 0x102e051e0>`
2. test01内存地址:`<function test01 at 0x103739158>`
3. inner内存地址:`<function outer.<locals>.inner at 0x103739268>`
4. test01内存地址:`<function outer.<locals>.inner at 0x103739268>`

图片

四、类装饰器
一、原理
1. 通过重写call方法实现

二、写法

​​​​​​​

import timeclass Decrator:    def __init__(self,fn):        self.fn = fn
    def __call__(self, *args, **kwargs):        start_time = time.time()        result = self.fn(*args, **kwargs)        end_time = time.time()        west_time = end_time - start_time        return result,west_time
@Decratordef sum(x,y):    print(sum)    return x+ysum(1,2)
 

三、执行过程分析

1. __call__()方法的作用其实是把一个类的实例化对象变成了可调用对象,使得类实例对象可以像调用普通函数那样,以“对象名()”的形式使用。

2. 当调用sum函数的时候,会先将sum函数作为参数传给Decrator类(通过类的`__init__`初始化函数接收),此时 fn =sum(x,y)(只是实例未调用)

3. 此时sum函数传递进来的参数为元组,就会赋值给了`__call__`方法,args

4. 此时sum函数传递进来的参数为字典,就赋值给了`__call__`方法,kwargs

5. 在`__call__`方法中做一系列操作之后,return self.fn(*args) 再传递给sum函数 *

6. *` __call__`方法返回的函数self.fn(*args是被装饰后的函数实例,然后传给sum函数执行 

7. `__call__`必须要return装饰后的函数,否则会报错

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

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

相关文章

[职场] 个人简历教育背景怎么填 #其他#笔记#媒体

个人简历教育背景怎么填 一个人的受教育程度很大部分决定了此人的专业素质&#xff0c;简历中的教育背景是HR衡量求职者的标准&#xff0c;因此教育背景部分在简历中比较靠前。 怎么写教育背景&#xff1f; 1、时间 首先&#xff0c;最重要的是你要注明好时间&#xff0c;时间都…

idea搭建spring5.3.x源码环境

1.写在前面的话 碰到了不少想阅读或者学习spring源码的同学&#xff0c;但是第一步搭建这个源码阅读环境就能难倒了一大批人。下面我就以spring5.3.x这个源码分支&#xff0c;来具体演示一下搭建过程。 2. 下载源码 下载源码这一步&#xff0c;说实话&#xff0c;由于某些原…

STM32控制DS18B20温度传感器获取温度

时间记录&#xff1a;2024/1/28 一、DS18B20温度传感器介绍 &#xff08;1&#xff09;测温范围-55℃~125℃&#xff0c;在-10℃到85℃范围内误差为0.4 &#xff08;2&#xff09;返回的温度数据为16位二进制数据 &#xff08;3&#xff09;STM32和DS18B20通信使用单总线协议…

算法模板 3.二分查找

二分查找 789. 数的范围 - AcWing题库 check函数&#xff08;lr&#xff08;这里要不要1&#xff09;&#xff09;>> 1 &#xff0c;要根据具体情况&#xff0c;如果是r mid的话lr就不用1&#xff0c;l mid的话就要1 #include <bits/stdc.h> using namespace s…

Android Retrofit添加header参数

前言 有些接口需要单独设置header参数 作为标记 如何灵活 或者统一设置请求header呢 注解Headers 顾名思义 Headers是指多个header 放在对象里 统一管理 //获取xxx Headers({"Content-Type: application/json","User-Agent: test"}) POST("xxxx&q…

小程序:类型三级分类

一、效果图片 二、代码 <template><view class"customPosition"><!-- header --><navBar :border"false" :hasBack"true" :title"titleName"></navBar><!-- 查询 --><view class"search…

JavaWeb之打包失败解决方案

情况描述&#xff1a; ---打包不成功 这时点击Maven中的蓝色小闪电&#xff1a; 小闪电的意思&#xff1a;是否跳过测试。点击选中就可以跳过&#xff0c;打包的时候就可以跳过测试代码。 再次打包后即可成功&#xff1a; 查看具体打包后的jar包&#xff1a; 打包后&#x…

openGaussdb5.0单点企业版部署_Centos7_x86

本文档环境&#xff1a;CentOS7.9 x86_64 4G1C40G python2.7.5 交互式初始化环境方式 介绍 openGauss是一款开源关系型数据库管理系统&#xff0c;采用木兰宽松许可证v2发行。openGauss内核深度融合华为在数据库领域多年的经验&#xff0c;结合企业级场景需求&#xff0c;持续…

Ubuntu远程连接登录信息解读(ubuntu登录信息、远程登录信息)

文章目录 1. Welcome to Ubuntu 20.04.4 LTS (GNU/Linux 5.4.0-100-generic aarch64)2. 三个链接是官方提供的文档、管理工具和技术支持3. System information as of Thu 01 Feb 2024 03:30:45 PM HKT4. System load: 1.16&#xff1a;系统负载指数5. Processes: 1096系统正在运…

虹科技术|一文详解IO-Link Wireless技术如何影响工业无线自动化

导读&#xff1a;在工业无线自动化的飞速发展进程中&#xff0c;IO-Link Wireless技术成为了一项具有颠覆性的创新。它将IO-Link协议与无线连接完美结合&#xff0c;解决了传统通信技术在工业应用中的痛点。本文将深入解析IO-Link Wireless技术的原理、应用领域、优势以及实际案…

vue3集成video.js

就长这个样子&#xff0c;该有的功能都有了 首先安装 npm install video.js 然后创建一个vue文件 <template><div class"full" style"padding: 10px;overflow: auto;"><video :id"videoId" class"video-js"><…

LeetCode.1686. 石子游戏 VI

题目 题目链接 分析 本题采取贪心的策略 我们先假设只有两个石头a,b&#xff0c; 对于 Alice 价值分别为 a1,a2&#xff0c; 对于 Bob 价值而言价值分别是 b1,b2 第一种方案是 Alice取第一个&#xff0c;Bob 取第二个&#xff0c;Alice与Bob的价值差是 c1 a1 - b1&#xf…

Django模型(八)

一、修改数据 先获取对象,通过对象属性更新数据,再保存 (更新单一数据)通过QuerySet的update函数更新数据 (更新多条数据) #单条记录修改 save c = Cook.objects.get(pk=1) c.name = 安妮 c.save()# 更新多个值 update Cook.objects.filter(sect=粤菜).update(level=5)1.1、…

游戏APP开发:从创意到实现的全过程

随着智能手机的普及和移动互联网的发展&#xff0c;游戏APP市场日益繁荣。游戏APP开发已经成为一个热门行业&#xff0c;吸引了众多开发者和创业者的关注。本文将介绍游戏APP开发的全过程&#xff0c;包括创意、策划、设计、开发、测试和发布等环节。 一、创意 游戏APP开发的…

测试access和trunk口的区别(华为)

思科设备参考&#xff1a;测试access和trunk口的区别&#xff08;思科&#xff09; 一&#xff0c;实验目的 实现同一 Vlan 内的主机互通&#xff0c;不同 Vlan 间的主机隔离。 二&#xff0c;配置前测试 PC1分别ping PC2、PC3、PC4都能通&#xff0c;因为四台PC默认同处于v…

2024年美赛F题Problem F Reducing Illegal Wildlife Trade减少非法野生动物贸易的完整思路代码分享

非法的野生动物贸易会对我们的环境产生负面影响&#xff0c;并威胁到全球的生物多样性。据估计&#xff0c;它每年涉及高达265亿美元&#xff0c;被认为是全球第四大非法交易。[1]你将开发一个由数据驱动的5年项目&#xff0c;旨在显著减少非法野生动物贸易。你的目标是说服一个…

2024 美国大学生数学建模竞赛 美赛(D题)五大湖水资源调配问题 国际大学生数学建模竞赛| 建模秘籍文章代码思路大全

铛铛&#xff01;小秘籍来咯&#xff01; 小秘籍希望大家都能轻松建模呀&#xff0c;华数杯也会持续给大家放送思路滴~ 抓紧小秘籍&#xff0c;我们出发吧~ 完整内容可以在文章末尾领取&#xff01; 问题一&#xff1a;建立一个包括五大湖和连接从苏必利尔湖到大西洋的河流的…

软件工程(最简式总结)

目录 第一章:概述 1.软件危机的表现原因 2.常见的软件开发方法包括&#xff1a; 3.软件工程基本原则 4.软件工程三要素 5.设计模式的分类 6.针对变换型数据流设计步骤 7.针对事务型数据流设计步骤 第二章&#xff1a;软件过程 1.软件生命周期 2.软件过程模型 &…

Maven dependency中的scope

Maven的一个哲学是惯例优于配置(Convention Over Configuration), Maven默认的依赖配置项中&#xff0c;scope的默认值是compile。 scope的分类 compile&#xff08;默认&#xff09; 含义&#xff1a; compile 是默认值&#xff0c;如果没有指定 scope 值&#xff0c;该元素…

SpringBoot引入主盘探活定时任务

主盘探活通常是指检查存储设备&#xff08;例如硬盘&#xff09;是否可读写&#xff0c;但在Java中并没有直接针对硬件级别的磁盘探活API。然而&#xff0c;我们可以模拟一个场景&#xff0c;即检查某个目录或文件是否可以被Java程序正常读写&#xff0c;以此作为主盘活跃的一个…