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

Python之装饰器-无参装饰器

Python之装饰器-无参装饰器

装饰器介绍

1. 为何要用装饰器

  • Python 中的装饰器是一种语法糖,可以在运行时,动态的给函数或类添加功能。
  • 装饰器本质上是一个函数,使用 @ + 函数名就是可实现绑定给函数的第二个功能 。
  • 将一些通用的、特定函数的功能抽象成一个装饰器,可以重复利用这些功能

2. 什么是装饰器

  • “装饰”代指为被装饰对象添加新的功能,“器”代指器具/工具
  • 装饰器的作用:就是在不修改被装饰对象源代码和调用方式的前提下为被装饰对象添加额外的功能。
  • 装饰器使用场景:插入日志、性能测试、事务处理、缓存、权限校验
  • 可以调用的有:函数、方法、类
  • 函数装饰器分为:无参装饰器和有参装饰,二者都是使用都是需要【名称空间+函数嵌套+闭包+函数对象的组合知识】
  • 使用“@”符号定义装饰器,前提是需要有一个函数作为工具然后被“@”装饰到其他函数头上,为这个函数添加功能

无参装饰器

  • @符号后是一个函数
  • 虽然是无参装饰器,但是@后的函数本质上是单参函数

def add(x, y):print(add.__name__, x, y)return x + yadd(4, 5)# 此函数记录了,调用了add函数,x和y的值是什么
# 返回结果:add 4 5
# 返回结果:9
import time # 时间底层模块
print('------')
time.sleep(10)
print('******')# 导入time模块,执行第1个print后,time.sleep(10) 休眠10秒,然后输出第2个print
# 返回结果:------
# 返回结果:******
import datetime # 导入datetime模块start = datetime.datetime.now() # 设置start,获取当前时间# 导入datetime模块
end = datetime.datetime.now() # 设置end,获取当前时间# end变量在下一个代码块中执行,稍微等几秒错开时间。
start, end # 记录的两个时间戳,用于记录开始时间和结束时间
# 返回结果:(datetime.datetime(2024, 3, 23, 11, 4, 2, 337816), datetime.datetime(2024, 3, 23, 11, 4, 4, 518772))
(end - start).total_seconds() # total.seonds 总秒数# end 减去 start 获取运行的秒数
# 返回结果:2.180956
def add(x, y):#print(add.__name__, x, y) # 这个只能记录add,sub呢?#time.sleep(2) # 修秒2秒return x + ydef logger(fn):ret = fn(4, 5)return retlogger(add)# base版,基于这版,增加功能、
# 返回结果:9
def add(x, y):#print(add.__name__, x, y) # 这个只能记录add,sub呢?#time.sleep(2)return x + ydef logger(fn, x, y):ret = fn(x, y)return retlogger(add, 4, 5)# 返回结果:9
def add(x, y):#print(add.__name__, x, y) # 你这个只能记录add,sub呢?#time.sleep(2)return x + ydef logger(fn, x, y):print(fn.__name__, x, y) # 增加记录值ret = fn(x, y)return retlogger(add, 4, 5)# 返回结果:add 4 5
# 返回结果:9
def add(x, y):#mylog(add.__name__, x, y) # 你这个只能记录add,sub呢?#time.sleep(2)return x + ydef sub(x, y): # 可以用于多个函数return x - ydef logger(fn, x, y):print(fn.__name__, x, y) # 增加记录值ret = fn(x, y)return retlogger(add, 4, 5)
logger(sub, 5, 6)# 返回结果:add 4 5
# 返回结果:sub 5 6
# 返回结果:-1
def add(x, y):#mylog(add.__name__, x, y) # 你这个只能记录add,sub呢?#time.sleep(2)return x + ydef sub(x, y, z): # 可以用于多个函数return x - y - zdef logger(fn, *args, **kwargs): # 接受关键字传参,位置传参。print(fn.__name__, args, kwargs) # 增加记录值print('执行前可以做的事情,增强')ret = fn(*args, **kwargs)print('执行后可以做的事情,增强')return retlogger(add, 4, y=8)
logger(sub, 5, 6, z=7)# 返回结果:add (4,) {'y': 8}
# 返回结果:执行前可以做的事情,增强
# 返回结果:执行后可以做的事情,增强
# 返回结果:sub (5, 6) {'z': 7}
# 返回结果:执行前可以做的事情,增强
# 返回结果:执行后可以做的事情,增强
# 返回结果:-8
def add(x, y):#mylog(add.__name__, x, y) # 你这个只能记录add,sub呢?#time.sleep(2)return x + ydef sub(x, y, z): # 可以用于多个函数return x - y - zdef logger(fn):def inner(*args, **kwargs):print(fn.__name__, args, kwargs) # 增加记录值print('执行前可以做的事情,增强')ret = fn(*args, **kwargs)print('执行后可以做的事情,增强')return retreturn innerlogger(add)(4, y=8)
#logger(sub, 5, 6, z=7)# 返回结果:add (4,) {'y': 8}
# 返回结果:执行前可以做的事情,增强
# 返回结果:执行后可以做的事情,增强
# 返回结果:12
def add(x, y):#time.sleep(2)return x + ydef sub(x, y, z): # 可以用于多个函数return x - y - zdef logger(fn):def inner(*args, **kwargs):print('执行前可以做的事情,增强', fn.__name__, args, kwargs)ret = fn(*args, **kwargs)print('执行后可以做的事情,增强')return retreturn innerlogger(add)(4, y=8)
#logger(sub, 5, 6, z=7)# 返回结果:执行前可以做的事情,增强 add (4,) {'y': 8}
# 返回结果:执行后可以做的事情,增强
# 返回结果:12
def add(x, y):#time.sleep(2)return x + ydef sub(x, y, z): # 可以用于多个函数return x - y - zdef logger(fn): # fn adddef inner(*args, **kwargs):print('执行前可以做的事情,增强', fn.__name__, args, kwargs)ret = fn(*args, **kwargs) # fn(4, y=8) add(4, y=8)print('执行后可以做的事情,增强')return retreturn innert = logger(add) # t = inner
print(t(4, y=8)) # inner(4, y=8)# 返回结果:执行前可以做的事情,增强 add (4,) {'y': 8}
# 返回结果:执行后可以做的事情,增强
# 返回结果:12
def add(x, y):#time.sleep(2)return x + ydef logger(fn): # fn adddef inner(*args, **kwargs):print('执行前可以做的事情,增强', fn.__name__, args, kwargs)ret = fn(*args, **kwargs) # fn(4, y=8) add(4, y=8)print('执行后可以做的事情,增强')return retreturn inner#t = logger(add) # t = inner
#print(t(4, y=8)) # inner(4, y=8)add = logger(add)
print(add(4, 5))# 返回结果:执行前可以做的事情,增强 add (4, 5) {}
# 返回结果:执行后可以做的事情,增强
# 返回结果:9

请添加图片描述

def add(x, y):#time.sleep(2)return x + ydef logger(fn): # fn adddef inner(*args, **kwargs):print('执行前可以做的事情,增强', fn.__name__, args, kwargs)ret = fn(*args, **kwargs) # fn(4, y=8) add(4, y=8)print('执行后可以做的事情,增强')return retreturn inner#t = logger(add) # t = inner
#print(t(4, y=8)) # inner(4, y=8)
print(hex(id(add))) # 打印add的id值
add = logger(add)
print(add(4, 5))
print(add.__closure__) # 查看add的closure中记录闭包# 返回结果:0x10954fd80
# 返回结果:执行前可以做的事情,增强 add (4, 5) {}
# 返回结果:执行后可以做的事情,增强
# 返回结果:9
# 返回结果:(<cell at 0x1083e3d90: function object at 0x10954fd80>,)
def logger(fn): # fn adddef inner(*args, **kwargs):print('执行前可以做的事情,增强', fn.__name__, args, kwargs)ret = fn(*args, **kwargs) # fn(4, y=8) add(4, y=8)print('执行后可以做的事情,增强')return retreturn inner@logger # 装饰器 #等价式, add = logger(add) # logger应该等效为单参函数
def add(x, y):#time.sleep(2)return x + y#t = logger(add) # t = inner
#print(t(4, y=8)) # inner(4, y=8)
#add = logger(add)
print(add(4, 5))# @装饰器语法,@标识符,把这一行下面一行的def定义的标识符作为其实参传入,返回值覆盖了下面这个标识符
# 返回结果:执行前可以做的事情,增强 add (4, 5) {}
# 返回结果:执行后可以做的事情,增强
# 返回结果:9
def logger(fn): def inner(*args, **kwargs):print('执行前可以做的事情,增强', fn.__name__, args, kwargs)ret = fn(*args, **kwargs) print('执行后可以做的事情,增强')return retreturn inner@logger # 装饰器 #等价式, add = logger(add) # logger应该等效为单参函数
def add(x, y):#time.sleep(2)return x + yprint(add(4, 5)) # 非侵入代码,完成了功能,并且好像从来没有装饰过一样
print(add.__name__) #add实际是inner# 返回结果:执行前可以做的事情,增强 add (4, 5) {}
# 返回结果:执行后可以做的事情,增强
# 返回结果:9
# 返回结果:inner
def logger(wrapped): def wrapper(*args, **kwargs):print('执行前可以做的事情,增强', wrapped.__name__, args, kwargs)ret = wrapped(*args, **kwargs) print('执行后可以做的事情,增强')return retreturn wrapper@logger # 装饰器 #等价式, add = logger(add) # logger应该等效为单参函数
def add(x, y):#time.sleep(2)return x + yprint(add(4, 5)) # 非侵入代码,完成了功能,并且好像从来没有装饰过一样
print(add.__name__)# 返回结果:执行前可以做的事情,增强 add (4, 5) {}
# 返回结果:执行后可以做的事情,增强
# 返回结果:9
# 返回结果:wrapper
def logger(wrapped): def wrapper(*args, **kwargs):start = datetime.datetime.now()ret = wrapped(*args, **kwargs) delta = (datetime.datetime.now() - start).total_seconds()print("{} tooks {}s.".format(wrapped.__name__, delta))return retreturn wrapper@logger # 装饰器 #等价式, add = logger(add) # logger应该等效为单参函数
def add(x, y):time.sleep(2)return x + yprint(add(4, 5)) # 非侵入代码,完成了功能,并且好像从来没有装饰过一样
print(add.__name__) # 返回结果:add tooks 2.002051s.
# 返回结果:9
# 返回结果:wrapper
http://www.lryc.cn/news/323830.html

相关文章:

  • 音视频实战--音视频编码
  • 【黄金手指】windows操作系统环境下使用jar命令行解压和打包Springboot项目jar包
  • React【Day1】
  • MNN 执行推理(九)
  • 算法公式汇总
  • c语言管理课程信息系统
  • 大模型在天体物理学研究中的辅助作用与案例分析
  • 洛谷_P1873 [COCI 2011/2012 #5] EKO / 砍树_python写法
  • Android_NDK调试
  • 全量知识系统 概要设计(SmartChat回复)
  • 一、SpringBoot基础搭建
  • some/ip CAN CANFD
  • HTTP Header Fields
  • 基于FPGA的FFT图像滤波设计
  • WPF 立体Border
  • java.lang.ClassNotFoundException: kotlin.jvm.internal.Intrinsics
  • 代码随想录(day8)——字符串
  • JavaScript 权威指南第七版(GPT 重译)(二)
  • 【python_往企业微信群中发送文件】
  • 华为校招机试 - 循环依赖(20240320)
  • 基于Spring Boot技术的幼儿园管理系统
  • 查找众数及中位数 - 华为OD统一考试(C卷)
  • bash命令执行.sh文件 windows python环境
  • refreactive vue3
  • 【项目实践Day06】异步请求与同步请求+Ajax+微信小程序上实现发送异步请求
  • Elasticsearch面试系列-01
  • QT tableWidget横向纵向设置
  • Unity Mesh简化为Cube mesh
  • openGauss学习笔记-249 openGauss性能调优-使用Plan Hint进行调优-Join顺序的Hint
  • 大规模预训练语言模型的可解释性研究与实践