Python装饰器的专业解释

装饰器,其实是用到了闭包的原理来进行操作的。

单个装饰器:

以下是一个简单的例子:

def outer(func):print("OUTER enter ...")def wrapper(*args, **kwargs):print("调用之前......")result = func(*args, **kwargs)print("调用之后......")return resultprint("OUTER leave ...")return wrapper@outer
def my_hello():print("hello world")

上面的代码可以运行出结果:

这个时候就会把这个闭包创建出来。

当我们调用my_hello函数的时候,会进行执行wrapper里的代码:

def outer(func):print("OUTER enter ...")def wrapper(*args, **kwargs):print("调用之前......")result = func(*args, **kwargs)print("调用之后......")return resultprint("OUTER leave ...")return wrapper@outer
def my_hello():print("hello world")my_hello()

调用原理:

等价于:

def outer(func):print("OUTER enter ...")def wrapper(*args, **kwargs):print("调用之前......")result = func(*args, **kwargs)print("调用之后......")return resultprint("OUTER leave ...")return wrapper# @outer
def my_hello():print("hello world")my_hello = outer(my_hello)
my_hello()

多重装饰器修饰:

def outer1(func):print("OUTER enter ...1")def wrapper(*args, **kwargs):print("调用之前......1")result = func(*args, **kwargs)print("调用之后......1")return resultprint("OUTER leave ...1")return wrapperdef outer2(func):print("OUTER enter ...2")def wrapper(*args, **kwargs):print("调用之前......2")result = func(*args, **kwargs)print("调用之后......2")return resultprint("OUTER leave ...2")return wrapper@outer1
@outer2
def my_hello():print("hello world")

打印的结果如下:

调用的时候:

def outer1(func):print("OUTER enter ...1")def wrapper(*args, **kwargs):print("调用之前......1")result = func(*args, **kwargs)print("调用之后......1")return resultprint("OUTER leave ...1")return wrapperdef outer2(func):print("OUTER enter ...2")def wrapper(*args, **kwargs):print("调用之前......2")result = func(*args, **kwargs)print("调用之后......2")return resultprint("OUTER leave ...2")return wrapper@outer1
@outer2
def my_hello():print("hello world")my_hello()

运行结果为:

调用原理:

def outer1(func):print("OUTER enter ...1")def wrapper(*args, **kwargs):print("调用之前......1")result = func(*args, **kwargs)print("调用之后......1")return resultprint("OUTER leave ...1")return wrapperdef outer2(func):print("OUTER enter ...2")def wrapper(*args, **kwargs):print("调用之前......2")result = func(*args, **kwargs)print("调用之后......2")return resultprint("OUTER leave ...2")return wrapper# @outer1
# @outer2
def my_hello():print("hello world")my_hello = outer2(my_hello)
my_hello = outer1(my_hello)my_hello()

运行结果如下:

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

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

相关文章

亚马逊云科技 re:Invent 2023 产品体验:亚马逊云科技产品应用实践 国赛选手带你看 Elasticache Serverless

抛砖引玉 讲一下作者背景,曾经参加过国内世界技能大赛云计算的选拔,那么在竞赛中包含两类,一类是架构类竞赛,另一类就是 TroubleShooting 竞赛,对应的分别为亚马逊云科技 GameDay 和亚马逊云科技 Jam,想必…

【数学建模美赛M奖速成系列】Matplotlib绘图技巧(三)

Matplotlib绘图技巧(三) 写在前面7. 雷达图7.1 圆形雷达图7.2 多边形雷达图 8. 极坐标图 subplot9. 折线图 plot10. 灰度图 meshgrid11. 热力图11.1 自定义colormap 12. 箱线图 boxplot 写在前面 终于更新完Matplotlib绘图技巧的全部内容,有…

php 8.4 xdebug扩展编译安装方法

最新版php8.4 xdebug扩展只能通过编译方式安装, pecl是安装不了的, 编译方法如下 下载最新版xdebug git clone https://github.com/xdebug/xdebug.git 却换入xdebug目录执行编译安装xdebug cd xdebug phpize./configure --enable-xdebugmakemake install3. 配置启用xdebug 这…

JavaScript中实现页面跳转的几种常用方法

Hi i,m JinXiang ⭐ 前言 ⭐ 本篇文章主要介绍在JavaScript中实现页面跳转的几种常用方法以及部分理论知识 🍉欢迎点赞 👍 收藏 ⭐留言评论 📝私信必回哟😁 🍉博主收将持续更新学习记录获,友友们有任何问题…

Linux:jumpserver资产管理,分配 (4)

jumpserver可以去管理,Linux,Windows和Windows server,数据库,华为,思科等…网络设备 我这里准备了 三个 分别为 centos7 win10 mysql 在jumpserver上等登录的话,还需要他们的用户去登录,这里等会我就一…

1panel使用指南(一)面板安装

一、1panel简介 1Panel是杭州飞致云信息科技有限公司推出的产品 [1],帮助用户实现快速建站。 [2]是一款现代化、开源的Linux服务器运维管理面板,于2023年3月推出,深度集成WordPress和Halo,一键完成域名绑定、SSL证书配置等操作&a…

SSH远程登陆服务器

截取自文章:SSH简介及两种远程登录的方法_ssh -CSDN博客 SSH的安装 SSH分为客户端 openssh-client 和服务器 openssh-server,可以利用以下命令确认电脑上是否安装了客户端和服务器。 dpkg -l | grep ssh 如果只是想远程登陆别的机器只需要安装客户端&…

Eureka服务注册与发现

1. Eureka简介 Eureka采用了CS的设计架构,Eureka Server 作为服务注册功能的服务器,它是服务注册中心。而系统中的其他微服务,使用 Eureka的客户端连接到 Eureka Server并维持心跳连接。这样系统的维护人员就可以通过 Eureka Server 来监控系…

【软件工程】漫谈增量过程模型:软件开发的逐步之道

🍎个人博客:个人主页 🏆个人专栏: 软件工程 ⛳️ 功不唐捐,玉汝于成 目录 前言: 正文 增量过程模型(Incremental Process Model) 主要特点和阶段: 优点&#xff1…

YOLOv5算法进阶改进(10)— 更换主干网络之MobileViTv3 | 轻量化Backbone

前言:Hello大家好,我是小哥谈。MobileViTv3是一种改进的模型架构,用于图像分类任务。它是在MobileViTv1和MobileViTv2的基础上进行改进的,通过引入新的模块和优化网络结构来提高性能。本节课就给大家介绍一下如何在主干网络中引入MobileViTv3网络结构,希望大家学习之后能够…

php学习05-常量

常量可以理解为值不变的量。常量值被定义后,在脚本的其他任何地方都不能改变。一个常量由英文字母、下划线和数字组成,但数字不能作为首字母出现。 在PHP中使用define()函数来定义常量,该函数的语法格式如下: define(string cons…

uni-app uni-app内置组件

锋哥原创的uni-app视频教程: 2023版uniapp从入门到上天视频教程(Java后端无废话版),火爆更新中..._哔哩哔哩_bilibili2023版uniapp从入门到上天视频教程(Java后端无废话版),火爆更新中...共计23条视频,包括:第1讲 uni…

MS6459字符叠加可兼容MAX7456

MS6459 是 OSD 电路,与 MCU 配合使用,可控制不同类型的显示系统。显示点阵为 1218,内置部分数字、英文字符、拉丁字符和中文字符。电路集成有上电复位电路和 VRAM 清零电路用于减轻 MCU 的工作量。 主要特点 输入信号:混合视频信号; 显示字符…

简单实现一个自定义loader

webpack定义的loader需要遵循单一功能原则,也就是一个loader只实现一个功能。在实现开发中,我们会直接使用诸如蓝湖等生成的样式,比如 button{background: rgb(255, 85, 46); }但为了考虑主题换肤,我们实现的想要的可能是 butto…

推荐系统/电商中的 业务指标GMV

GMV(Gross Merchandise Volume)是指在一定时间内,一个电商平台上所有商品的总销售价值,通常以货币单位(例如美元、人民币等)表示。GMV是一个关键的电商业务指标,用于衡量平台的交易规模和业务增…

使用YOLOv8和Grad-CAM技术生成图像热图

目录 yolov8导航 YOLOv8(附带各种任务详细说明链接) 概述 环境准备 代码解读 导入库 定义letterbox函数 调整尺寸和比例 计算填充 应用填充 yolov8_heatmap类定义和初始化 后处理函数 绘制检测结果 类的调用函数 热图生成细节 参数解释 we…

java go c++ 开源全文搜索引擎

Apache Lucene Java 全文搜索框架 许可证:Apache-2.0 开发语言:Java 官网:https://lucene.apache.org/ Apache Lucene 是完全用 Java 编写的高性能、功能齐全的全文检索引擎架构,提供了完整的查询引擎和索引引擎、部分文本分析引…

C语言经典算法【每日一练】20

题目&#xff1a;有一个已经排好序的数组。现输入一个数&#xff0c;要求按原来的规律将它插入数组中。 1、先排序 2、插入 #include <stdio.h>// 主函数 void main() {int i,j,p,q,s,n,a[11]{127,3,6,28,54,68,87,105,162,18};//排序&#xff08;选择排序&#xff09…

【力扣题解】P654-最大二叉树-Java题解

&#x1f468;‍&#x1f4bb;博客主页&#xff1a;花无缺 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 花无缺 原创 收录于专栏 【力扣题解】 文章目录 【力扣题解】P654-最大二叉树-Java题解&#x1f30f;题目描述&#x1f4a1;题解&#x1f30f;总结…

三菱人机交互GT Designer的使用(二,开关,指示灯,数值显示,数值输入)

今天也开始每日一学&#xff0c;内容为开关&#xff0c;指示灯&#xff0c;数值显示&#xff0c;数值输入&#xff0c;以为这篇文章比较长&#xff0c;所有小编决分为3篇内容写完&#xff0c;谢谢大家阅读&#xff0c;不足之处&#xff0c;欢迎指正。 目录 开关 位&#xff0c…