python之无参装饰器

2023-05-16

在讲装饰器之前,要知道以下知识点
一、储备知识点
1.*args,**kwargs

def index(x,y):
	print(x,y)

def wrapper(*args,**kwargs):
	index(*args,**kwargs) #index(y = 222,x = 111)
wrapper(y = 222, x = 111)

2.名称空间与作用域:名称空间的‘嵌套’关系是在函数定义阶段,即检测语法的时候确定的。

3.函数对象
可以把函数当做参数传入
可以把行数当做返回值返回

def index():
	pass
def foo(func):
	return func
foo(index)
#不要加括号,加括号是先运行了inndex了,不要加括号!不加括号代表的是传的是函数

4.函数的嵌套定义

def outter(func):
	def wrapper():
		pass
	return wrapper

闭包函数

def outter():
	x = 111
	def wrapper():
		x
	return wrapper #重新回到全局

f =outter()

传参的方式一:通过参数的形式为函数体传值

def wrapper():
	print(1)
	print(2)
	print(3)
	x

传参的方式二:通过闭包的函数体传值

1.
def outter(x):
	#x=1
	def wrapper():
		print(1)
		print(2)
		print(3)
		x
	return wrapper
	#return outter内的wrapper那个函数的内存地址

f1 = outter(1)
f2 = outter(2)
f3 = outter(3)

wrapper = outter(1)

2.
def outter(x):
	#x=11
	def wrapper():
		x
	return wrapper

wrapper = outter(1)

二、装饰器
1.什么是装饰器?
器指的是工具,可以定义成函数
装饰指的是为其他事物添加额外的东西点缀
合在一起:
装饰器指的是定义一个函数,该函数是用来为其他函数添加额外的功能

2.为什么要用装饰器?
开放封闭原则
开放:指的是对拓展功能是开放的
封闭:指的是对修改源代码是封闭的
装饰器就是在不修改被装饰器对象源代码以及调用方式的前提下为被装饰对象添加新功能

3.如何用?

需求:在不修改index函数的源代码以及调用方式的前提下为其添加统计运行时间的功能

def index(x,y):
	print('index %s %s'%(x,y))

index(111,222,)
index(x=111,y=222)

方案一:失败
问题:没有修改被装饰对象的调用方式,但是修改了其源代码

import time
def index(x,y):
	start = time.time()
	time.sleep(3)
	print('index %s %s' %(x,y))
	stop = time.time()
	print(stop - start)

index(111,222)

方案二:
问题:没有修改被装饰对象的调用方式,也没有修改其源代码,并且加上了新功能,但是代码冗余。

import time
def index(x,y):
	time.sleep(3)
	print('index %s %s' %(x,y))

start = time.time()
index(111,222)
stop = time.time()
print(stop-start)
#多次使用造成的代码冗余
start = time.time()
index(111,222)
stop = time.time()
print(stop-start)

start = time.time()
index(111,222)
stop = time.time()
print(stop-start)

start = time.time()
index(111,222)
stop = time.time()
print(stop-start)

方案三:
问题:解决了方案二代码冗余的问题,但是带来了一个新问题,函数的调用方式改变了

import time
def index(x,y):
	time.sleep(3)
	print('index %s %s' %(x,y))

def wrapper():
	start = time.time()
	index(111,222)
	stop = time.time()
	print(stop - start)

wrapper()

方案三的优化一:将index的参数写活了

import time
def index(x,y,z):
	time.sleep(3)
	print('index %s %s %s' %(x,y,z))

def wrapper(*args,**kwargs):
	start = time.time()
	index(*args,**kwargs)
	stop = time.time()
	print(stop - start)

wrapper(111,222,333)
wrapper(333,y = 444,z=555)

方案三的优化二:在优化一的基础上把被装饰对象写活了,原来只能装饰index

import time
def index(x,y,z):
	time.sleep(3)
	print('index %s %s %s' %(x,y,z))

def home(name):
	time.sleep(2)
	print('welcome %s to home page' % name)

def outter(func): #func = index的内存地址
	#func=index的内存地址
	def wrapper(*args,**kwargs):
		start = time.time()
		func(*args,**kwargs) #index的内存地址()
		stop = time.time()
		print(stop - start)
	return wrapper
index = outter(index) #f = outter(index的内存地址)
#index = 当初那个wrapper函数的内存地址
index(x = 1, y= 2, z= 3)

方案三的优化三:将wrapper做的跟被装饰对象一模一样,以假乱真

import time
def index(x,y,z):
	time.sleep(3)
	print('index %s %s %s' %(x,y,z))
def home(name):
	time.sleep(2)
	print('welcome %s to home page' % name)
	return 123
def outter(func): 
	def wrapper(*args,**kwargs):
		start = time.time()
		res = func(*args,**kwargs) 
		stop = time.time()
		print(stop - start)
		return res
	return wrapper
#偷梁换柱:home这个名字指向的wrapper函数的内存地址
home = outter(home)
res = home('egon')
print('返回值-->',res)

语法糖:让你开心的糖

import time
##装饰器
def timmer(func):
	def wrapper(*args,**kwargs):
		start = time.time()
		res = func(*args,**kwargs) 
		stop = time.time()
		print(stop - start)
		return res
	return wrapper
	
##在被装饰对象正上方单独的以行写@装饰器名字及
@timmer  #index = timmer(index)
def home(name):
	time.sleep(2)
	print('welcome %s to home page' % name)
	return 123

 #偷梁换柱:home这个名字指向的wrapper函数的内存地址
#
 index (x = 1, y = 2, z = 3)
 home('egon')
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python之无参装饰器 的相关文章

随机推荐

  • 信号量的使用

    信号量 英文名字 xff1a semaphore 这里的进程信号量会为下列的信号量打基础 Ucos系统的信号量c线程的信号量java进程和线程的信号量 信号量作用 当多个进程 线程进行共享操作时 xff0c 用于资源保护 xff0c 以防止
  • 海康威视摄像头对接SDK实时预览功能和抓拍功能,懒癌福利,可直接CV

    海康威视摄像头完成实时预览功能和抓拍功能 背景思路 流程开发步骤1 海康的SDK xff0c 只需要在项目启动的时候初始化一次就行 xff0c 所以我直接将初始化SDK和加载DLL库的代码丢到启动类中去了 xff1a 2 先讲实时预览功能
  • 一、什么是SLAM?

    书中定义 xff1a slam是指移动智能体从一个未知环境里未知地点出发 xff0c 在运动过程中通过自身传感器观测周围环境 xff0c 并根据环境定位自身位置 xff0c 再根据自身的位置进行增量式的地图构建 xff0c 从而达到同时定位
  • ROS 创建工作空间流程

    本文以移植代码为例说明 目标是把一款云台SDK中的ROS代码部分抠出来移植到自己创建的工作空间中 记录下大致的流程 目录 1 创建工作空间 2 编译工作空间 xff08 可选 xff09 3 设置环境变量 xff08 可选 xff09 4
  • 边缘计算系列之MEC介绍

    前言 上篇内容 xff0c 跟大家简单介绍了边缘计算发展现状和边缘计算的基本概念 今天 xff0c 我们来讲讲MEC 目录 一 MEC的基本概念 二 MEC和边缘计算的关系 三 MEC的价值和优势 四 运营商MEC白皮书 1 MEC的基本概
  • 元学习(meta learning) 最新进展综述论文,28页pdf

    关注上方 深度学习技术前沿 xff0c 选择 星标公众号 xff0c 资源干货 xff0c 第一时间送达 xff01 本文综述了元学习在图像分类 自然语言处理和机器人技术等领域的应用 与深度学习不同 xff0c 元学习使用较少的样本数据集
  • 王海峰、李飞飞、山世光、王井东、汪玉……众多AI华人学者入选2022 IEEE Fellow...

    来源 xff1a 机器之心 北京时间 11 月 24 日凌晨 xff0c IEEE 公布了 2022 年度新一届会士的入选完整名单 IEEE 全称是美国电子电气工程师学会 xff08 Institute of Electrical and
  • 博后年薪58万起,副教授35万起,出站享80万安家费或100万房补,西电杭州研究院...

    来源 博士后招聘平台 编辑 硕博就业圈 研究院简介 XDU HANGZHOU 西安电子科技大学杭州研究院是西安电子科技大学为深入贯彻落实党中央 国务院关于深化产教融合改革部署和教育部 国家发展改革委 财政部关于加快新时代研究生教育改革发展的
  • 为什么要使用事件委托,使用事件委托的好处

    事件委托在我们程序员应聘阶段好多人都会被面试官问及到 xff0c 那到底什么是事件委托呢 xff1f 其实啊 xff0c 事件委托是本应给子元素注册的事件 xff0c 注册在父元素身上 然后使用 e tage方法由父元素统一分配给每个触发了
  • C++类和对象——友元

    目录 xff08 1 xff09 xff0c 全局函数做友元 xff08 2 xff09 xff0c 类做友元 xff08 3 xff09 xff0c 成员函数做友元 类中的私有属性 xff0c 也想让类外特殊的函数或者类进行访问 xff0
  • ubuntu系统安装TVM(保姆级)

    下载tvm span class token function git span clone recursive https github com apache tvm tvm 建议开代理 下载完成后在主目录看到tvm文件夹 依赖工具安装
  • Linux防火墙——Firewalld防火墙规则(内含防火墙的配置方法、图形化工具、firewall-cmd命令 )

    文章目录 Firewalld防火墙的配置一 Firewalld防火墙的配置方法运行时配置永久配置 二 Firewall config图形工具配置运行时配置 永久配置重新加载防火墙关联网卡到指定区域修改默认区域连接状态 区域 选项卡 服务 选
  • 人生苦短,我用k8s--------------Pod概念与Pod网络通讯方式详解

    一 pod概念 Pod是kubernetes中你可以创建和部署的最小也是最简的单位 Pod代表着集群中运行的进程 Pod中封装着应用的容器 xff08 数量大于等于1 xff0c docker最常用 xff0c 也可使用其他的 xff09
  • 装饰器三种写法之带参数的装饰器

    装饰器是AOP编程思想 xff0c 给主体函数增加功能 xff0c 又不让代码入侵到主体函数中 xff0c 实现高内聚 xff0c 低耦合 如果装饰功能部分代码也需要参数的话 xff0c 可以在原来的两层函数外面再加一层 xff0c 专门用
  • 把Linux下外设的USB端口号映射到固定的名字

    目录 1 固定USB设备的端口号的原理 2 rules文件的编写方法 3 映射结果查看 1 固定USB设备的端口号的原理 近期调试了一款云台 xff0c 控制方面需要用到串口通信 xff0c 调试过程中发现了一个问题 xff0c 就是 Li
  • GCC 消除编译器的特定警告

    GCC allows the user to selectively enable or disable certain types of diagnostics and change the kind of the diagnostic
  • 输入一个int型整数,按照从右向左的阅读顺序,返回一个不含重复数字的新的整数。 保证输入的整数最后一位不是0。

    题目描述 输入一个int型整数 xff0c 按照从右向左的阅读顺序 xff0c 返回一个不含重复数字的新的整数 保证输入的整数最后一位不是0 输入描述 输入一个int型整数 输出描述 按照从右向左的阅读顺序 xff0c 返回一个不含重复数字
  • C#WinForm

    WinForm 是 Windows Form 的简称 xff0c 是基于 NET Framework 平台的客户端 xff08 PC软件 xff09 开发技术使用 C 编程 C WinForm 编程需要创建Windows窗体应用程序项目 W
  • Mininet命令学习【mininet-上】【C4-01】

    文章目录 1 网络构建参数 topo1 单一 xff08 single xff09 拓扑2 线形 xff08 linear xff09 拓扑3 树形 xff08 tree xff09 拓扑4 自定义 xff08 custom xff09 拓
  • python之无参装饰器

    在讲装饰器之前 xff0c 要知道以下知识点 一 储备知识点 1 args xff0c kwargs span class token keyword def span span class token function index spa