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

Python高频面试题——装饰器(带大家理解装饰器的本质)

装饰器概念

装饰器本质上是一个python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限验证等场景,装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。

装饰器代码实战

友情提示:接下来的代码有点多,希望大家可以拷贝下来,实际运行一下,相信会对装饰器这个概念有更为深刻的理解!

给大家举个例子,定义一个now函数 输出当前时间

def now ():print(time.strftime("%Y-%m-%d-%H_%M_%S", time.localtime()))

现在,假设我们要增强now()函数的功能,比如,在函数调用前后自动打印日志,但又不希望修改now()函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。

本质上,decorator就是一个返回函数的高阶函数。所以,我们要定义一个能打印日志的decorator,可以定义如下:

def log(func):def wrapper(*args, **kw):print('call start:' +func.__name__)func(*args, **kw)print('call end:' + func.__name__)return wrapper

这是一个较为固定的写法:

参数func表示传入的函数对象

wrapper是内部函数,return wrapper 会实现对其调用

(*args, **kw)是一种固定用法,表示可以传入任意的参数,*args和**kw分别属于非关键字参数和关键字参数,两者也都是可变参数。一个星号*加上参数名,比如*number,定义后,number可以接收任意数量的参数,并将它们储存在一个tuple中。关键字参数的特征是两个星号**加上参数名,比如**kw, 定义后,kw将接收到的任意数量参数存到一个dict中。举个例子就懂了

def func_para(*args, **kw):print ('args:',args )print ('kw:',kw )func_para(1,2,3,4, a=1,b=2,c=3)

输出:

args: (1, 2, 3, 4)

kw: {'a': 1, 'b': 2, 'c': 3}

func(*args, **kw) 表示对传入的函数进行调用,调用前后分别执行了两条print语句

func.__name__ 表示函数的名字

def wrapper 根据需求也可以return 某个值。

最后调用装饰器的代码如下:在now上面加上装饰器 @log即可

def func_para(*args, **kw):print ('args:',args )print ('kw:',kw )func_para(1,2,3,4, a=1,b=2,c=3)
@log
def now ():print(time.strftime("%Y-%m-%d-%H_%M_%S", time.localtime()))
now()

输出:

call start:now

2023-03-10-15_08_40

call end:now

看到这里有的同学可能会问,如果now()函数需要增加参数怎么办?很简单,我们无须对装饰器log进行任何修改,代码如下:

@log
def now (a,b):print(a)print(time.strftime("%Y-%m-%d-%H_%M_%S", time.localtime()))print(b)
now("test1","test2")

输出:

call startnow

test1

2023-03-10-15_08_40

test2

call end:now

装饰器的本质

其实想要了解装饰器的本质,我们需要了解python的函数对象!python中一切皆是对象,所以函数也不例外,我们还是以下面代码为例

def now ():print(time.strftime("%Y-%m-%d-%H_%M_%S", time.localtime()))
print(now)
print(type(now))

输出:

<function now at 0x000001C7C5D44F78>

<class 'function'>

可以看到输出了now对象的地址和对应的类型。我们也可以理解函数的名字就是函数在内存中对应的地址

我们可以把函数赋值:

a=now

print(a)

此时输出的a 的值与print(now) 是一样的!

我们也可以把函数作为参数传递,例如

import time
def now():print(time.strftime("%Y-%m-%d-%H_%M_%S", time.localtime()))def func_demo(func):return func #调用作为参数传入的函数func1=func_demo(now)
func1()

输出:

2023-03-10-15_18_44

讲到这里,我们可以看出来

@log

def now ():

其实等价于

log(now)

这里now作为了装饰器函数log的参数,@log只是语法糖而已,语法糖是计算机语言中特殊的某种语法,这种语法对语言的功能并没有影响,对于程序员有更好的易用性,能够增加程序的可读性。大家可以结合前面讲解的def log函数的代码,然后执行以下代码

import time
def log(func):def wrapper(*args, **kw):print('call start:' + func.__name__)func(*args, **kw)print('call end:' + func.__name__)return wrapper
@log
def now ():print(time.strftime("%Y-%m-%d-%H_%M_%S", time.localtime()))d=log(now)
d()

会输出:

call start:wrapper

call start:now

2023-03-10-15_29_47

call end:now

call end:wrapper

相关文章:

Python高频面试题——装饰器(带大家理解装饰器的本质)

装饰器概念装饰器本质上是一个python函数&#xff0c;它可以让其他函数在不需要做任何代码变动的前提下增加额外功能&#xff0c;装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景&#xff0c;比如&#xff1a;插入日志、性能测试、事务处理、缓存、权限验证等场景…...

全方位解读智能中控屏发展趋势!亚马逊Alexa语音+Matter能力成必备

随着智能家居行业逐步从碎片化的智能单品阶段&#xff0c;迈向体验更完整的全屋互联阶段&#xff0c;智能中控屏作为智能家居最佳的入口之一&#xff0c;在年轻人青睐全屋智能装修的风潮下&#xff0c;市场潜力彻底被引爆。 一、为什么是智能中控屏&#xff1f; 在智能音箱增…...

JAVA练习74-括号生成

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 3月10日练习内容 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、题目-…...

Java ORM开发 更全面的应用场景

1. 一个web系统, 想支持多种数据库, 如同时要用mysql, oracle 需要动态切换数据源? 2. 读写分离, 但读库与写库是不同的类型, 如分别是: mysql, oracle 3. 智能化自动过滤null和空字符串&#xff0c;不再需要写判断非空的代码。 4.动态/任意组合查询条件,不需要提前准备da…...

SpringBoot【基础篇】---- 基础配置

SpringBoot【基础篇】---- 基础配置1. 属性配置2. 配置文件分类3. yaml 文件4. yaml 数据读取1. 读取单一数据2. 读取全部数据3. 读取对象数据yaml 文件中的数据引用1. 属性配置 SpringBoot 通过配置文件 application.properties 就可以修改默认的配置&#xff0c;那咱们就先找…...

手机磁吸背夹散热器制冷快速方案

手机散热器是什么&#xff1f;手机散热器分为几种类型&#xff1f;手机散热的方式都有哪些&#xff1f; 因为经常玩游戏&#xff0c;手机发热得厉害&#xff0c;都可以煎鸡蛋了&#xff0c;心想着要买个东西给手机散散热&#xff0c;没想到还真的有手机散热器。 不知道手机散…...

青岛OJ(QingdaoU/OnlineJudge)部署如何直连数据库批量修改

1.postgres数据库QingdaoU/OnlineJudge用的数据库是postgreSQL&#xff0c;一个关系型数据库。默认端口是5432&#xff0c;我们下载一个navcat 15以上的版本&#xff0c;用来连数据库。2.修改docker-compose.yml文件修改docker-compose.yml&#xff0c;手动添加一个端口&#x…...

渗透测试——信息收集(详细)

信息收集&#xff1a;前言&#xff1a;信息收集是渗透测试除了授权之外的第一步&#xff0c;也是关键的一步&#xff0c;尽量多的收集目标的信息会给后续的渗透事半功倍。收集信息的思路有很多&#xff0c;例如&#xff1a;页面信息收集、域名信息收集、敏感信息收集、子域名收…...

什么是谐波

什么是谐波 目录 1. 问题的提出 2. “谐”字在中英文中的原意 2.1 “谐”字在汉语中的原义 2.2 “谐”字对应的英语词的原义 3.“harmonics(谐波)”概念是谁引入物理学中的&#xff1f; 4.“harmonics(谐波)”的数学解释 1. 问题的提出 “谐波”这个术语用于各种学科&am…...

技术报告:程序员如何开发一个商城型购物网站

前言随着互联网的快速发展&#xff0c;电商行业正成为越来越多人的选择。而作为电商行业的主要参与者之一&#xff0c;商城型购物网站的开发则成为程序员不可避免的任务之一。本文将对商城型购物网站的开发进行详细阐述&#xff0c;包括需求分析、架构设计、技术选型、前后端开…...

DPDK系列之八虚拟化virtio

一、virtio的介绍 在一篇文章中对virtio进行了简单的说明。在早期的虚拟化的过程中&#xff0c;无论是KVM还是Vmware亦或是Xen&#xff0c;每个平台想当然的是自己搞自己的IO接口。这就和现在国内的互联各个平台都是大而全一样&#xff0c;怎么可能我用你的支付接口呢&#xf…...

直播间与2位优秀创作者分享经历

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 昨天&#xff0c;卢松松的直播间好像又被推荐给了2.9万人观看&#xff0c;讲了一个小时后直播间的人数一直攀升&#xff0c;最终冲破了2万人大关。晚些时候&#xff0c;白杨SEO也来到了我的直播间&…...

linux上快速安装 Flarum 指南

一、安装Composer Composer是PHP的依赖管理器(类似于Node.js的npm或Python的 pip ),它可用于当前流行的PHP平台,例如Drupal、Magento等。那么如何安装PHP Composer呢?本文将为大家介绍下在Debian 10上安装PHP Composer的教程。 在安装 Composer 之前,请确保您的 Debian …...

数学不好,英语不行,非本专业,可以学IT吗?

看到很多想入行IT编程的小伙伴&#xff0c;都会问一些比较类似的问题。 比如&#xff1a; 不是计算机专业的&#xff0c;可以学编程吗&#xff1f; 数学一直就不好&#xff0c;可以转行学IT吗&#xff1f; 学编程开发&#xff0c;对英语的要求会不会很高&#xff1f; 01、…...

软件测试13

Linux命令 1.pwd&#xff1a;查看当前所在的路径位置 2.ls&#xff1a;查看当前路径下有哪些文件 3.cd&#xff1a;切换路径 4.touch&#xff1a;创建普通文件&#xff0c;可以创建单文件&#xff0c;也可以创建多文件&#xff08;touch a&#xff0c;touch b c&#xff09; 5…...

React(八):引出Hook、useState、useEffect的使用详解

React&#xff08;八&#xff09;一、类组件的优劣势1.类组件的优势2.类组件的劣势&#xff08;1&#xff09;复杂组件会难以理解&#xff08;2&#xff09;复杂的class&#xff08;3&#xff09;组件复用状态很难二、Hook初体验useState1.使用Hook的计数器案例2.详解useState&…...

32*4VKL128 LQFP44超低功耗/超低工作电流/抗干扰LCD液晶段码驱动IC/LCD驱动芯片(IC) 适用于激光/红外线测距仪

产品型号&#xff1a;VKL128产品品牌&#xff1a;永嘉微电/VINKA封装形式&#xff1a;LQFP44产品年份&#xff1a;新年份原厂&#xff0c;工程服务&#xff0c;技术支持&#xff01;VKL128概述:VKL128是一个点阵式存储映射的LCD驱动器&#xff0c;可支持最大128点&#xff08;3…...

自定义控件(?/N) - 事件分发

一、外部传递到ViewGroup中Activity会通过 getWindow( ) 获取PhoneWindow对象并调用它的superDispatchTouchEvent( )&#xff0c;该方法会调用它&#xff08;PhoneWindow&#xff09;的内部类 DecorView 的 superDispatchTouchEvent( )&#xff0c;而它&#xff08;DecorView&a…...

诗一样的代码命名规范

有文化&#xff1a;落霞与孤鹜齐飞&#xff0c;秋水共长天一色&#xff1b;没文化&#xff1a;太阳落山的时候&#xff0c;看见一只鸟在水上飞&#xff1b;日常编码中&#xff0c;代码的命名是个大的学问。能快速的看懂开源软件的代码结构和意图&#xff0c;也是一项必备的能力…...

L1-010 比较大小 L1-030 一帮一 L1-015 跟奥巴马一起画方块 L1-035 情人节

本题要求将输入的任意3个整数从小到大输出。 输入格式: 输入在一行中给出3个整数&#xff0c;其间以空格分隔。 输出格式: 在一行中将3个整数从小到大输出&#xff0c;其间以“->”相连。 输入样例: 4 2 8 输出样例: 2->4->8 // 题目链接 https://pintia.cn/prob…...

大话软工笔记—需求分析概述

需求分析&#xff0c;就是要对需求调研收集到的资料信息逐个地进行拆分、研究&#xff0c;从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要&#xff0c;后续设计的依据主要来自于需求分析的成果&#xff0c;包括: 项目的目的…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾&#xff1a; 在上一篇中&#xff0c;我们成功地为应用集成了数据库&#xff0c;并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了&#xff01;但是&#xff0c;如果你仔细审视那些 API&#xff0c;会发现它们还很“粗糙”&#xff1a;有…...

怎么让Comfyui导出的图像不包含工作流信息,

为了数据安全&#xff0c;让Comfyui导出的图像不包含工作流信息&#xff0c;导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo&#xff08;推荐&#xff09;​​ 在 save_images 方法中&#xff0c;​​删除或注释掉所有与 metadata …...

WebRTC从入门到实践 - 零基础教程

WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC&#xff1f; WebRTC&#xff08;Web Real-Time Communication&#xff09;是一个支持网页浏览器进行实时语音…...

Spring Security 认证流程——补充

一、认证流程概述 Spring Security 的认证流程基于 过滤器链&#xff08;Filter Chain&#xff09;&#xff0c;核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤&#xff1a; 用户提交登录请求拦…...

Linux安全加固:从攻防视角构建系统免疫

Linux安全加固:从攻防视角构建系统免疫 构建坚不可摧的数字堡垒 引言:攻防对抗的新纪元 在日益复杂的网络威胁环境中,Linux系统安全已从被动防御转向主动免疫。2023年全球网络安全报告显示,高级持续性威胁(APT)攻击同比增长65%,平均入侵停留时间缩短至48小时。本章将从…...

负载均衡器》》LVS、Nginx、HAproxy 区别

虚拟主机 先4&#xff0c;后7...