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函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限验证等场景…...
全方位解读智能中控屏发展趋势!亚马逊Alexa语音+Matter能力成必备
随着智能家居行业逐步从碎片化的智能单品阶段,迈向体验更完整的全屋互联阶段,智能中控屏作为智能家居最佳的入口之一,在年轻人青睐全屋智能装修的风潮下,市场潜力彻底被引爆。 一、为什么是智能中控屏? 在智能音箱增…...
JAVA练习74-括号生成
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 前言 提示:这里可以添加本文要记录的大概内容: 3月10日练习内容 提示:以下是本篇文章正文内容,下面案例可供参考 一、题目-…...
Java ORM开发 更全面的应用场景
1. 一个web系统, 想支持多种数据库, 如同时要用mysql, oracle 需要动态切换数据源? 2. 读写分离, 但读库与写库是不同的类型, 如分别是: mysql, oracle 3. 智能化自动过滤null和空字符串,不再需要写判断非空的代码。 4.动态/任意组合查询条件,不需要提前准备da…...
SpringBoot【基础篇】---- 基础配置
SpringBoot【基础篇】---- 基础配置1. 属性配置2. 配置文件分类3. yaml 文件4. yaml 数据读取1. 读取单一数据2. 读取全部数据3. 读取对象数据yaml 文件中的数据引用1. 属性配置 SpringBoot 通过配置文件 application.properties 就可以修改默认的配置,那咱们就先找…...
手机磁吸背夹散热器制冷快速方案
手机散热器是什么?手机散热器分为几种类型?手机散热的方式都有哪些? 因为经常玩游戏,手机发热得厉害,都可以煎鸡蛋了,心想着要买个东西给手机散散热,没想到还真的有手机散热器。 不知道手机散…...
青岛OJ(QingdaoU/OnlineJudge)部署如何直连数据库批量修改
1.postgres数据库QingdaoU/OnlineJudge用的数据库是postgreSQL,一个关系型数据库。默认端口是5432,我们下载一个navcat 15以上的版本,用来连数据库。2.修改docker-compose.yml文件修改docker-compose.yml,手动添加一个端口&#x…...
渗透测试——信息收集(详细)
信息收集:前言:信息收集是渗透测试除了授权之外的第一步,也是关键的一步,尽量多的收集目标的信息会给后续的渗透事半功倍。收集信息的思路有很多,例如:页面信息收集、域名信息收集、敏感信息收集、子域名收…...
什么是谐波
什么是谐波 目录 1. 问题的提出 2. “谐”字在中英文中的原意 2.1 “谐”字在汉语中的原义 2.2 “谐”字对应的英语词的原义 3.“harmonics(谐波)”概念是谁引入物理学中的? 4.“harmonics(谐波)”的数学解释 1. 问题的提出 “谐波”这个术语用于各种学科&am…...
技术报告:程序员如何开发一个商城型购物网站
前言随着互联网的快速发展,电商行业正成为越来越多人的选择。而作为电商行业的主要参与者之一,商城型购物网站的开发则成为程序员不可避免的任务之一。本文将对商城型购物网站的开发进行详细阐述,包括需求分析、架构设计、技术选型、前后端开…...
DPDK系列之八虚拟化virtio
一、virtio的介绍 在一篇文章中对virtio进行了简单的说明。在早期的虚拟化的过程中,无论是KVM还是Vmware亦或是Xen,每个平台想当然的是自己搞自己的IO接口。这就和现在国内的互联各个平台都是大而全一样,怎么可能我用你的支付接口呢…...
直播间与2位优秀创作者分享经历
我是卢松松,点点上面的头像,欢迎关注我哦! 昨天,卢松松的直播间好像又被推荐给了2.9万人观看,讲了一个小时后直播间的人数一直攀升,最终冲破了2万人大关。晚些时候,白杨SEO也来到了我的直播间&…...
linux上快速安装 Flarum 指南
一、安装Composer Composer是PHP的依赖管理器(类似于Node.js的npm或Python的 pip ),它可用于当前流行的PHP平台,例如Drupal、Magento等。那么如何安装PHP Composer呢?本文将为大家介绍下在Debian 10上安装PHP Composer的教程。 在安装 Composer 之前,请确保您的 Debian …...
数学不好,英语不行,非本专业,可以学IT吗?
看到很多想入行IT编程的小伙伴,都会问一些比较类似的问题。 比如: 不是计算机专业的,可以学编程吗? 数学一直就不好,可以转行学IT吗? 学编程开发,对英语的要求会不会很高? 01、…...
软件测试13
Linux命令 1.pwd:查看当前所在的路径位置 2.ls:查看当前路径下有哪些文件 3.cd:切换路径 4.touch:创建普通文件,可以创建单文件,也可以创建多文件(touch a,touch b c) 5…...
React(八):引出Hook、useState、useEffect的使用详解
React(八)一、类组件的优劣势1.类组件的优势2.类组件的劣势(1)复杂组件会难以理解(2)复杂的class(3)组件复用状态很难二、Hook初体验useState1.使用Hook的计数器案例2.详解useState&…...
32*4VKL128 LQFP44超低功耗/超低工作电流/抗干扰LCD液晶段码驱动IC/LCD驱动芯片(IC) 适用于激光/红外线测距仪
产品型号:VKL128产品品牌:永嘉微电/VINKA封装形式:LQFP44产品年份:新年份原厂,工程服务,技术支持!VKL128概述:VKL128是一个点阵式存储映射的LCD驱动器,可支持最大128点(3…...
自定义控件(?/N) - 事件分发
一、外部传递到ViewGroup中Activity会通过 getWindow( ) 获取PhoneWindow对象并调用它的superDispatchTouchEvent( ),该方法会调用它(PhoneWindow)的内部类 DecorView 的 superDispatchTouchEvent( ),而它(DecorView&a…...
诗一样的代码命名规范
有文化:落霞与孤鹜齐飞,秋水共长天一色;没文化:太阳落山的时候,看见一只鸟在水上飞;日常编码中,代码的命名是个大的学问。能快速的看懂开源软件的代码结构和意图,也是一项必备的能力…...
L1-010 比较大小 L1-030 一帮一 L1-015 跟奥巴马一起画方块 L1-035 情人节
本题要求将输入的任意3个整数从小到大输出。 输入格式: 输入在一行中给出3个整数,其间以空格分隔。 输出格式: 在一行中将3个整数从小到大输出,其间以“->”相连。 输入样例: 4 2 8 输出样例: 2->4->8 // 题目链接 https://pintia.cn/prob…...
GTK+命令行神器Zenity:在Ubuntu 22.04上快速创建图形对话框的保姆级指南
GTK命令行神器Zenity:在Ubuntu 22.04上快速创建图形对话框的保姆级指南 如果你是一位Linux桌面用户或开发者,经常需要在命令行和图形界面之间切换,那么Zenity绝对是你的得力助手。这款轻量级的GTK命令行工具,能够让你在Shell脚本中…...
企者不立,跨者不行,SAP UI5 开发里的克制、分寸与长久之道
老子这句话放到 SAP UI5 开发里看,并不是在劝开发者不进取,也不是叫我们少写功能、少做创新。它真正提醒的是,企业级前端开发最怕一种姿态,脚尖踮得很高,步子跨得很大,心里急着证明自己聪明,手上急着把每一个需求都做成个性化杰作。SAP UI5 最终运行在 SAP Fiori Launch…...
如何用AI技术5分钟搞定视频硬字幕提取?这个开源工具让你轻松生成SRT字幕文件
如何用AI技术5分钟搞定视频硬字幕提取?这个开源工具让你轻松生成SRT字幕文件 【免费下载链接】video-subtitle-extractor 视频硬字幕提取,生成srt文件。无需申请第三方API,本地实现文本识别。基于深度学习的视频字幕提取框架,包含…...
AI辅助生殖:多模态数据融合与深度学习在胚胎评估中的应用
1. 项目概述:当AI遇见生命的起点在辅助生殖技术(ART)这个关乎无数家庭希望的前沿领域,每一次胚胎移植都像是一场精密的“押注”。医生和胚胎学家们需要在显微镜下,从数个甚至数十个胚胎中,挑选出那个最有潜…...
前端自定义光标系统:从原理到工程实践
1. 项目概述:一个可深度定制的网页光标系统最近在做一个前端项目时,遇到了一个挺有意思的需求:用户希望网页上的光标不仅仅是默认的箭头或小手,而是能根据不同的交互状态、页面区域甚至用户偏好,动态切换成各种自定义的…...
零知识证明与法律科技融合:构建可验证计算驱动的自动化合约执行系统
1. 项目概述与核心价值最近在开源社区里,一个名为Sheygoodbai/vericlaw的项目引起了我的注意。乍一看这个项目名,可能会觉得有些抽象,但深入探究后,我发现它触及了当前一个非常前沿且充满潜力的交叉领域:如何利用可验证…...
Conforme配置管理范式:类型安全与约定优先的实践指南
1. 项目概述:Conforme,一个被低估的配置管理范式在软件开发和系统运维的日常里,我们总在和“配置”打交道。数据库连接字符串、API密钥、功能开关、环境变量……这些看似零散的信息,却像乐谱上的音符,共同决定了应用如…...
轻量级Web代理moltron:架构解析与生产级部署实战
1. 项目概述:一个轻量级、高性能的Web代理工具在开发和运维的日常工作中,我们经常需要处理不同网络环境下的服务访问问题。比如,本地开发需要调试一个部署在内网测试环境的API,或者需要安全地访问某些仅限特定网络访问的资源。传统…...
长曜创新获数千万元 A+ 融资,Tron Ultra 割草机器人年中全球发售破行业难题
硬氪获悉,智能庭院机器人公司「长曜创新」近日完成数千万元 A 融资,此前 A 轮融资也已在 2025 年 12 月完成,半年累计超亿元。其最新产品 Tron Ultra 系列将在年中全球发售。融资情况与发展方向长曜创新近日完成数千万元 A 轮融资,…...
2026 年豆包开启付费订阅,中国 AI 大模型商业化迎来大考!
豆包更新付费订阅,打破行业免费格局2026 年 5 月 4 日,字节跳动旗下 AI 产品豆包在苹果 App Store 悄然更新付费订阅方案。标准版 68 元/月、加强版 200 元/月、专业版 500 元/月,这三档价格梯度划破了中国 AI 大模型行业持续两年的“免费狂欢…...
