Python装饰器的具体实用示例
示例1:普通装饰器
def name(n):def func(x):res = n(x+x)return resreturn func@name
def run(x): # run = name(run)print(x)if __name__ == '__main__':run(1)
# 2
def name(n):def func(*x):res = n(x+x)return resreturn func@name
def run(x): # run = name(run)print(x)if __name__ == '__main__':run(1)
# (1, 1)
上述二者的比较,注意传参参数。一个是普通的传值,一个是两个元组相加。
示例2:普通装饰器传值
def name(n):def func(x, y):res = n(x,y)return resreturn func@name
def run(x, y): # run = name(run)print(x, y)if __name__ == '__main__':run(1, 2)
# 1 2
试想,如何才能实现1+2,run函数中还是name函数中
def name(n):def func(x, y):res = n(x,y)return resreturn func@name
def run(x, y): # run = name(run)print(x + y)if __name__ == '__main__':run(1, 2)
在run函数中实现,name函数作用近似于调用的操作,也可以在name函数中实现
def name(n):def func(x, y):res = n(x,y)print(x + y)return resreturn func@name
def run(x, y): # run = name(run)# print(x + y)passif __name__ == '__main__':run(1, 2)
示例3-进阶:日志
import loggingdef name(n):def func(x, y):res = n(x,y)logging.basicConfig(format='%(asctime)s %(name)s %(levelno)s %(filename)s ''%(lineno)d %(message)s', level=logging.DEBUG)logging.info("执行了{},{},结果是{}".format(x,y,res))return resreturn func@name
def run(x, y): # run = name(run)return x+yif __name__ == '__main__':run(1, 2)
# 2023-03-01 12:24:10,474 root 20 ceshi_test.py 10 执行了1,2,结果是3
这里的结果貌似没有指明函数,影响不大,可以看看logging模块,也可以自己加。
import loggingdef name(n):def func(x, y):res = n(x,y)logging.basicConfig(format='%(asctime)s %(name)s %(levelno)s %(filename)s ''%(lineno)d %(funcName)s %(message)s', level=logging.DEBUG)logging.info("执行了{},{},{},结果是{}".format(n.__name__,x,y,res))return resreturn func@name
def run(x, y): # run = name(run)return x+yif __name__ == '__main__':run(1, 2)
# 2023-03-01 12:35:15,283 root 20 ceshi_test.py 9 func 执行了run,1,2,结果是3
可以看到,获取的运行函数其实不太一样。要想准确的获取,建议手写
示例4-进阶:时间计时器
import time
def timer(clock):def func(*args,**kwargs):start = time.time()res = clock(*args,**kwargs)print("耗时 {} S".format(time.time() - start))return resreturn func@timer
def run(x, y): time.sleep(1)print(x + y)if __name__ == '__main__':run(1, 2)
# 3
# 耗时 1.0103626251220703 S
上述是在不做任何操作的情况下,单纯用来计算程序运行时间。
示例5-再进阶-带参
def outwapper(out):def country(cont):def inwapper(*args,**kwargs):if out == '中国':print("你好啊,兄弟")else:print("你是哪个国家的")cont(*args,**kwargs)return inwapperreturn country@outwapper("中国")
def people():passif __name__ == '__main__':people()
是不是看起来麻烦了很多,仔细一看其实也久那么回事。传个参数,该返回的值还是得返回。
def outwapper(out):def country(cont):def inwapper(*args,**kwargs):if out == '中国':print("你好啊,兄弟")else:print("你是哪个国家的")cont(*args,**kwargs)return inwapperreturn country@outwapper("中国")
@outwapper("俄罗斯")
def people():passif __name__ == '__main__':people()
# 你好啊,兄弟
# 你是哪个国家的
可以多个装饰器作用同一个函数上,也能重复使用。
示例6-高阶-类装饰器
class Time(object):def __init__(self, func):self.func = funcdef __call__(self, *args, **kwargs):print(args,kwargs)@Time
def name():passif __name__ == '__main__':name()
套用格式即可,__init__中的参数是必须的,因为需要传递函数。
class Time(object):def __init__(self, func):self.func = funcdef __call__(self, *args, **kwargs):print(args,kwargs)@Time
def name(x,y):passif __name__ == '__main__':name('清安',age=18)
# ('清安',) {'age': 18}
很明显了吧,__call__中用来接收值并处理的。
传参
class Time(object):def __init__(self, func):self.func = funcdef __call__(self, evt):def wapper(*args, **kwargs):print(self.func, args, kwargs)return wapper@Time("中国")
def name(x, y):passif __name__ == '__main__':name('清安', age=18)
# 中国 ('清安',) {'age': 18}
evt是啥?
class Time(object):def __init__(self, func):self.func = funcdef __call__(self, evt):def wapper(*args, **kwargs):print(evt.__name__, args, kwargs)return wapper@Time("中国")
def name(x, y):print(x,y)if __name__ == '__main__':name('清安', age=18)
# name ('清安',) {'age': 18}
就是name函数的函数地址,如何使用evt参数呢?
class Time(object):def __init__(self, func):self.func = funcdef __call__(self, evt):def wapper(*args, **kwargs):evt(args,kwargs)# print(evt.__name__, args, kwargs)return wapper@Time("中国")
def name(x, y):print(x,y)if __name__ == '__main__':name('清安', age=18)
就是这么简单。
示例7-高阶-装饰类的装饰器
def func(cls):def inwapper(*args,**kwargs):print(cls.__name__)print(args)return inwapper@func
class User:def __init__(self,name):self.name = nameif __name__ == '__main__':User("清an")
# User
# ('清an',)
类中函数使用装饰器
def func(cls):def inwapper(x, *args, **kwargs):logging.basicConfig(format='%(asctime)s %(name)s %(levelno)s %(filename)s ''%(lineno)d %(funcName)s %(message)s', level=logging.DEBUG)logging.info("执行了{},结果是{},{},{}".format(cls.__name__,x, args, kwargs))return inwapper# @func
class User:@funcdef name(self, name, name1, age):# return name, name1, agepass
if __name__ == '__main__':u = User()u.name("清安","ANAN",age=18)
2023-03-01 18:36:36,310 root 20 ceshi_test.py 74 inwapper 执行了name,结果是<__main__.User object at 0x0000020A11DABE50>,('清安', 'ANAN'),{'age': 18}
为什么要有个x,因为self会被当作参数传递,直接把内存地址一起传走了,要么下标取值要么再来个参数接收这个self。要么类中不使用self
❝既然使用了self,那么装饰器中能用来调用属性吗,答案是当然可以。
❞
def func(cls):def inwapper(x, *args, **kwargs):logging.basicConfig(format='%(asctime)s %(name)s %(levelno)s %(filename)s ''%(lineno)d %(funcName)s %(message)s', level=logging.DEBUG)x.info = 1logging.info("执行了{},结果是{},{},{}".format(cls.__name__,x, args, kwargs))return inwapperclass User:info = None@funcdef name(self, name, name1, age):# return name, name1, agepass
if __name__ == '__main__':u = User()u.name("清安","ANAN",age=18)print(u.info)
# 1
# 2023-03-02 09:15:36,640 root 20 ceshi_test.py 75 inwapper 执行了name,结果是<__main__.User object at 0x0000021B20A2F5B0>,('清安', 'ANAN'),{'age': 18}
❝显而易见,赋值成功。再来看看对其他函数赋值。
❞
def func(cls):def inwapper(x, *args, **kwargs):logging.basicConfig(format='%(asctime)s %(name)s %(levelno)s %(filename)s ''%(lineno)d %(funcName)s %(message)s', level=logging.DEBUG)x.Info("QA",18)logging.info("执行了{},结果是{},{},{}".format(cls.__name__,x, args, kwargs))return inwapperclass User:info = None@funcdef name(self, name, name1, age):# return name, name1, agepassdef Info(self,name,age):print("我是{},今年{}".format(name,age))if __name__ == '__main__':u = User()u.name("清安","ANAN",age=18)
# 2023-03-02 09:19:26,910 root 20 ceshi_test.py 75 inwapper 执行了name,结果是<__main__.User object at 0x00000232FF01F5B0>,('清安', 'ANAN'),{'age': 18}
# 我是QA,今年18
示例8-伪装
from functools import wrapsdef timer(value):def func(fun):# @wraps(fun)def inner(*args,**kwargs):res = fun()print(value)print(inner.__name__)return resreturn innerreturn func@timer("QA")
def run():passif __name__ == '__main__':run()
❝伪装装饰器,让装饰器函数名称指向运行函数名。
❞
此外还有一些用法,此处就不再阐述,学习完上述的示例后,你是否能自己写出一个像样的装饰器呢?
相关文章:
Python装饰器的具体实用示例
示例1:普通装饰器 def name(n):def func(x):res n(xx)return resreturn funcname def run(x): # run name(run)print(x)if __name__ __main__:run(1) # 2def name(n):def func(*x):res n(xx)return resreturn funcname def run(x): # run name(run)pr…...
谈谈我对Retrofit源码的理解
文章目录一、Retrofit简介二、使用介绍2.1 app / build.gradle添加依赖2.2 创建 Retrofit 实例2.3 创建 API 接口定义文件2.4 使用 Retrofit 进行网络请求三、源码分析3.1 创建 Retrofit 实例: 建造者模式创建Retrofit3.2 实例化API接口: 动态代理模式3.3 获取Observable返回值…...
八股文(三)
目录 一、 如何理解原型与原型链 二、 js继承 三、 vuex的使用 1.mutation和action的区别 mutation action 2.Vuex都有哪些API 四、 前端性能优化方法 五、 类型判断 题目 (1)typeof判断哪个类型会出错(即结果不准确)&…...
2023最新实施工程师面试题
1、两电脑都在同一个网络环境中,A 电脑访问不到 B 电脑的共享文件。此现象可能是哪些 方面所导致?怎样处理? 答:首先你要确定是不是在一个工作组内,只有在一个工作组内才可以共享文件,然后看一个看一看有没有防火墙之类的,然后确定文件是不是已经共享 2、 电脑开机时风扇…...
安卓逆向_6 --- JNI 和 NDK
Java 本机接口规范内容:https://docs.oracle.com/en/java/javase/19/docs/specs/jni/index.html JNI官方中文资料:https://blog.csdn.net/yishifu/article/details/52180448 NDK 官方文档:https://developer.android.google.cn/training/ar…...
Pod控制器
K8S之控制器详解#简介#在kubernetes中,按照Pod的创建方式可以将其分为两类:自主式:kubernetes直接创建出来的Pod,这种Pod删除后就没有了,也不会重建。控制器创建pod:通过Pod控制器创建的Pod,这种Pod删除之后还会自动重…...
微服务到云原生
微服务到云原生 微服务 微服务架构(Microservice Architecture)是一种架构概念,旨在通过将功能分解到各个离散的服务中以实现对解决方案的解耦。 微服务是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成。系统中的各…...
Spring Security 实现自定义登录和认证(1):使用自定义的用户进行认证
1 SpringSecurity 1.1 导入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId> </dependency>1.2 编写配置类 在spring最新版中禁用了WebSecurityConfigurerAdapter…...
Spring Cloud(微服务)学习篇(七)
Spring Cloud(微服务)学习篇(七) 1.使用代码的方式实现流量限制规则 1.1 变更SentinelController类 1.1.1 加入的代码 //流控限制 (一个或多个资源限流), postConstruct注解的作用是保证项目一启动就会加载,// 一个rule就是一个规则PostConstructpublic void FlowRule(){Li…...
嵌入式安防监控项目——前期知识复习
目录 一、概述 二、C语言 三、数据结构 四、IO进程 五、网络 六、ARM体系结构和接口技术 七、系统移植 八、内核驱动 一、概述 我再报班之前学过51和32,不过都是自学的。报班开始先从应用层入手的,C语言和数据结构。只要是个IT专业的大学这都是必…...
SpringAOP——基础知识
AOP AOP全称是Aspect Oriented Programming 即面向切面编程,是对一类统一事务的集中处理 例如,我们的网页许多地方都需要进行登陆验证,这时就需要在很多地方添加重复的验证代码,而AOP可以集中配置需要登陆验证的地方,…...
kafka3.0安装使用
一:定义 Kafka传 统定义:Kafka是一个分布式的基于发布/订阅模式的消息队列(Message Queue),主要应用于大数据实时处理领域。 Kafka最 新定义 : Kafka是 一个开源的 分 布式事件流平台 (Event St…...
Centos7(阿里云)_安装Mysql8.0
1.安装MySQL 新人可以试用一个月的阿里云,centos7的 一开始可能确实会自带mariadb,所以可以在网上随便找个教程开始尝试安装MySQL,当然大概率出错,然后此时你的rpm下面已经有了一个版本的mysql安装包。 以我为例,随便…...
【Java】JVM
一、介绍 1.什么是JVM? JVM是一种用于计算设备的规范,它是一个虚构出来的机器,是通过在实际的计算机上仿真模拟各种功能实现的。JVM包含一套字节码指令集,一组寄存器,一个栈,一个垃圾回收堆和一个存储方法域。JVM屏…...
Linux 和数据库笔记-06
今日内容介绍全天内容无需立马掌握MySQL 的高级功能应用数据库设计ER模型定义: E 代表实体(数据表), R 代表联系(数据表之间对应的字段)关系常见分类一对一一对多多对多外键如果…...
MySQL面试题-事务篇
1.事务的特性(ACID) 事务(Transaction)是指一组操作被看作是一个不可分割的工作单元,这组操作要么全部执行成功,要么全部执行失败。事务的特性通常用 ACID 四个单词来描述,它们分别代表原子性&…...
Linux嵌入式开发 | 汇编驱动LED(1)
文章目录🚗 🚗Linux嵌入式开发 | 汇编驱动LED(1)🚗 🚗初始化IO🚗 🚗STM32🚗 🚗使能GPIO时钟🚗 🚗设置IO复用🚗 Ƕ…...
什么是EventLoop?怎么测试Node或页面的性能
Event Loop 机制大家应该都有了解。本文利用 EventLoop 去做一个有趣的检测node或页面性能的代码,顺便介绍了一下EventLoop,希望对大家有所帮助! Event Loop Event Loop 机制大家应该都有了解。我先重复总结一下。 Node.js 和 Javascript 的…...
1018 锤子剪刀布 1025 反转链表
现给出两人的交锋记录,请统计双方的胜、平、负次数,并且给出双方分别出什么手势的胜算最大。 输入格式: 输入第 1 行给出正整数 N(≤10 5 ),即双方交锋的次数。随后 N 行,每行给出一次交锋的信…...
卷积神经网络的原理及实现
专栏:神经网络复现目录 卷积神经网络 本章介绍的卷积神经网络(convolutional neural network,CNN)是一类强大的、为处理图像数据而设计的神经网络。 基于卷积神经网络架构的模型在计算机视觉领域中已经占主导地位,当今…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...
安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
