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.mzph.cn/news/588671.shtml

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

相关文章

【Vue2+3入门到实战】(17)VUE之VueCli脚手架自定认创建项目、ESlint代码规范与修复、 ESlint自动修正插件的使用 详细示例

目录 一、本节内容二、VueCli 自定义创建项目三、ESlint代码规范及手动修复1.JavaScript Standard Style 规范说明2.代码规范错误3.手动修正 四、通过eslint插件来实现自动修正 一、本节内容 VueCli脚手架自定认创建项目ESlint代码规范与修复ESlint自动修正插件 二、VueCli 自…

FA模板制作流程

1、FA模板制作的流程(完整复制模板制作) 总结: FA完整复制云桌面模板流程: 1、安装一个全新的Windows,挂载并安装tools 2、关闭防火墙、启动administrator本地超管用户 3、挂载FusionAccess_WindowsDesktop_Instal…

C/C++面向对象(OOP)编程-回调函数详解(回调函数、异步编程、函数指针、)

本文主要介绍回调函数的使用,包括函数指针、异步回调编程、主要通过详细的例子来指导在异步编程和事件编程中如何使用回调函数来实现。 🎬个人简介:一个全栈工程师的升级之路! 📋个人专栏:C/C精进之路 &…

黑马程序员SSM框架-SpringBoot

视频连接:SpringBoot-01-SpringBoot工程入门案例开发步骤_哔哩哔哩_bilibili SpringBoot简介 入门程序 也可以基于官网创建项目。 SpringBoot项目快速启动 下面的插件将项目运行所需的依赖jar包全部加入到了最终运行的jar包中,并将入口程序指定。 Spri…

【网络面试(2)】DNS原理-域名和IP地址的查询转换

从上一篇博客我们得知浏览器是如何生成了HTTP消息了,但是浏览器作为应用程序,是不具备向网络中发送请求的能力,而是需要委托给操作系统的内核协议栈来发送请求。在委托协议栈之前,浏览器还要做的一件事情就是将域名转换为IP地址。…

java进阶(三)

IO与网络编程 3 输入输出流IO3.1 基础定义3.2 IO框架3.3 读取字节输入流-InputStream3.3.1 InputStream.read3.3.2 FileInputStream类说明 3.4读取字符输入流Reader3.4.1 Reader.read3.4.2 FileReader类说明 3.5 字节输出流OutputStream3.5.1 OutputStream.write3.5.2 FileOutp…

nodejs微信小程序+python+PHP特困救助供养信息管理系统-计算机毕业设计推荐

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性:…

分库分表之Mycat应用学习四

4 分片策略详解 分片的目标是将大量数据和访问请求均匀分布在多个节点上,通过这种方式提升数 据服务的存储和负载能力。 4.1 Mycat 分片策略详解 总体上分为连续分片和离散分片,还有一种是连续分片和离散分片的结合,例如先 范围后取模。 …

基于AT89C51单片机可做实物的温度烟雾火灾报警设计

点击链接获取Keil源码与Project Backups仿真图: https://download.csdn.net/download/qq_64505944/88658141?spm1001.2014.3001.5503 C 源码仿真图毕业设计实物制作步骤02 摘要 随着现代家庭用火、用电量的增加,家庭火灾发生的频率越来越高。火灾报警…

浅学lombok

Lombok(Project Lombok)是一个用于 Java 编程语言的开源库,旨在减少 Java 代码中的冗余和样板代码,提高开发人员的生产力。它通过使用注解来自动生成 Java 类的常见方法和代码,从而使开发人员能够编写更简洁、更具可读…

ColibriSM v1.4.2 已注册– 仿脸书类社交网络PHP源码

ColibriSM:当代社交网络平台的崛起 一、开篇与概述 在信息时代的浪潮中,社交媒体成为了人们日常生活中不可或缺的一部分。ColibriSM,作为一个仿照脸书(Facebook)、推特(Twitter)和照片墙&#…

WPF 新手指引弹窗

新手指引弹窗介绍 我们在第一次使用某个软件时,通常会有一个“新手指引”教学引导。WPF实现“新手指引”非常方便,且非常有趣。接下来我们就开始制作一个简单的”新手指引”(代码简单易懂,便于移植),引用到我们的项目中又可添加一…

Windows电脑引导损坏?按照这个教程能修复

前言 Windows系统的引导一般情况下是不会坏的,小伙伴们可以不用担心。发布这个帖子是因为要给接下来的文章做点铺垫。 关注小白很久的小伙伴应该都知道,小白的文章都讲得比较细。而且文章与文章之间的关联度其实还是蛮高的。在文章中,你会遇…

使用uni-app editor富文本组件设置富文本内容及解决@Ready先于onload执行,无法获取后端接口数据的问题

开始使用富文本组件editor时,不知如何调用相关API设置富文本内容和获取内容,本文将举例详解 目录 一.了解editor组件的常用属性及相关API 1.属性常用说明 2.富文本相关API说明 1)editorContext 2) editorContext.setContents…

【Leetcode】第 378 场周赛

文章目录 100166. 检查按位或是否存在尾随零题目题意代码 100185. 找出出现至少三次的最长特殊子字符串 I题目思路代码 100184. 找出出现至少三次的最长特殊子字符串 II 100166. 检查按位或是否存在尾随零 题目 题意 这里题目要求的是或运算,所以原数组中只需要有…

LeetCode每日一题.04(不同路径)

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。 问总共有多少条不同的路径? 示例 1…

Spring Cloud + Vue前后端分离-第10章 基于阿里云OSS的文件上传

源代码在GitHub - 629y/course: Spring Cloud Vue前后端分离-在线课程 Spring Cloud Vue前后端分离-第10章 基于阿里云OSS的文件上传 前面介绍的文件上传是基于本地文件服务器的文件上传,但是自己搭文件服务器会有很多运维的问题,比如磁盘满了要扩容…

Spark SQL简介与基本用法

Apache Spark是一个强大的分布式计算框架,Spark SQL是其组件之一,用于处理结构化数据。Spark SQL可以使用SQL查询语言来查询和分析数据,同时还提供了与Spark核心API的无缝集成。本文将深入探讨Spark SQL的基本概念和用法,包括数据…

Flink Job 执行流程

Flink On Yarn 模式 ​ 基于Yarn层面的架构类似 Spark on Yarn模式,都是由Client提交App到RM上面去运行,然后 RM分配第一个container去运行AM,然后由AM去负责资源的监督和管理。需要说明的是,Flink的Yarn模式更加类似Spark on Ya…

mysql间隙锁demo分析

概述 通常用的mysql都是innodb引擎; 一般在update的时候用id都会认为是给行记录加锁; 在使用非唯一索引更新时,会遇到临键锁(范围锁); 临键锁和表中的数据有关; mysq版本:8 隔离级别&#xf…