Py装饰器
装饰器:
1.定义,什么是装饰器
装饰器本质是一个函数,它是为了给其他函数添加附加功能
2.装饰器的两个原则
原则1 不修改被修饰函数的源代码
原则2 不修改被修饰函数的调用方式
3.首先来看一个统计运行时间的程序
import time
def cal(l):
start_time=time.time()
res=0
for i in l:
time.sleep(0.02)
res=i+res
stop_time=time.time()
print('函数的运行时间是%s' %(stop_time-start_time))
cal(range(0,100))
4.但是有可能其他函数还有很多,如果在执行其他的程序的时候也想计算一下
运行时间,就要每次重新写上这个,十分麻烦,所以需要装饰器
装饰器=高阶函数+函数嵌套+闭包
函数嵌套定义:def里面再def一个
高阶函数定义:函数接收的参数是一个函数名或者函数返回值是一个函数名
闭包的定义:包就是变量,闭包就是封装变量。里面的变量名找不到时就往外层找
import time
def shit():
time.sleep(3)
print('you are eating shit')
#以下是装饰器函数测量函数的运行时间
def timmer(func):
print(func)
start_time=time.time()
func()
stop_time=time.time()
print('函数的运行时间是',(stop_time-start_time))
#主程序,调用方式
timmer(shit)
#并不修改原函数
shit()
import time
def shit(): #原始函数
time.sleep(3)
print('you are eating shit')
#以下是装饰器函数测量函数的运行时间
def timmer(func):
def wrapper():
start_time=time.time()
func()
stop_time=time.time()
print('运行时间为',stop_time-start_time)
return wrapper
#主程序
res = timmer(shit) #由于返回值是wrapper的地址,所以res是wrapper地址
res() #执行wrapper函数
shit() #可以看见并不影响原函数
5.注意@timemer相当于 shit= timmer(shit)
先把timmer执行了,然后获得的是wrapper的内存地址,然后把shit给wrapper
执行了之后再
因此以下要加上装饰器的时候只需要在想加装饰器的函数的前面加上@timmer
示例
#以下是装饰器函数测量函数的运行时间
import time
def timmer(func):
def wrapper():
start_time=time.time()
func()
stop_time=time.time()
print('运行时间为',stop_time-start_time)
return wrapper
@timmer
def shit(): #原始函数
time.sleep(3)
print('you are eating shit')
return '是返回值'
shit() #加上@timmer之后,直接调用就可以了
但是这个程序存在一个小问题,就是执行加装装饰器之后得不到shit函数里面的
返回值
6.针对上一个程序里面的问题,优化后的方法
#以下是装饰器函数测量函数的运行时间
import time
def timmer(func):
def wrapper():
start_time=time.time()
res=func()
stop_time=time.time()
print('运行时间为',stop_time-start_time)
return res
return wrapper
@timmer
def shit(): #原始函数
time.sleep(3)
print('you are eating shit')
return '是返回值'
shit() #加上@timmer之后,直接调用就可以了
但是这个程序还是有小问题,就是如果要修饰的函数里不止一个参数
比如shit函数变成def shit(ab,cd),那就会运行出错
7.由于不同的函数可能有不同个数的参数,可以进行以下的形式的修改
#以下是装饰器函数测量函数的运行时间
import time
def timmer(func):
def wrapper(*args,**kargs):
start_time=time.time()
res=func(*args,**kargs)
stop_time=time.time()
print('运行时间为',stop_time-start_time)
return res
return wrapper
@timmer
def shit(name,age,dap): #原始函数
time.sleep(3)
print('you are eating shit')
return '是返回值'
res=shit('aa',12,56)
解压序列:
如果想从很大的一条列表中抽出头和尾,除了使用[]的方式抽,还可以
使用解压的方式
l1=[23,45,8,4,5,8,4,53,82,254,'as']
a,b,*_,d=l1 #这句话解压把整个列表分成了几部分
print(a) #a是23
print(d) #d是as
print(b) #b是45
print(_) #_是除去abd剩下的那些部分
验证功能装饰器
def auth_func(func):
def wrapper(*args, **kwargs):
username = input('用户名')
password = input('密码')
if username == 'sb' and password == '123':
res=func(*args, **kwargs)
return res
else:
print('用户名或者密码错误')
return wrapper
@auth_func
def index():
print('欢迎来到主页')
@auth_func
def home():
print('欢迎回家 ')
index()
home()
时还需要重新输入用户名和密码
改良:加入登录状态的判别
user_dic={'login':False}
def auth_func(func):
def wrapper(*args, **kwargs):
if user_dic['login']==1:
res=func(*args, **kwargs)
return res
username = input('用户名')
password = input('密码')
if username == 'sb' and password == '123':
user_dic['login']=1
res=func(*args, **kwargs)
return res
else:
print('用户名或者密码错误')
return wrapper
@auth_func
def index():
print('欢迎来到主页')
@auth_func
def home():
print('欢迎回家 ')
index()
home()
user_dic={'login':False}
def aurhorlog(authortype=0): #外面可以嵌套多一层,这样可以指定传多点参数
def auth_func(func): #上面那层有authortype,因此下面可以直接操作这参数
def wrapper(*args, **kwargs):
if user_dic['login']==1:
res=func(*args, **kwargs)
return res
username = input('用户名')
password = input('密码')
if username == 'sb' and password == '123':
user_dic['login']=1
res=func(*args, **kwargs)
return res
else:
print('用户名或者密码错误')
return wrapper
return auth_func
#@aurhorlog()是语法糖,它相当于下面的几句话
# auth_func = aurhorlog(authortype=1)
# wrapper = auth_func(index)
# index=wrapper()
@aurhorlog()
def index():
print('欢迎来到主页')
@aurhorlog()
def home():
print('欢迎回家 ')
index()
home()
重点:装饰器格式
#装饰器总共是三层
def fun(ptcanshu1=1): #第一层的里面可以弄一个普通参数
def fun1(func): #第二层里是func,它代表着准备要被装饰的函数
def wrapper(): #第三层里不放参数
print('hello')
func() #此处为调用要被装饰的函数
return wrapper
return fun1
@fun()
def shit():
print('shit')
shit()
def pt1(ptcanshu2=1):
def pt2(ptcanshu3=3):
def fun(ptcanshu1=1): #第一层的里面可以弄一个普通参数
def fun1(func): #第二层里是func,它代表着准备要被装饰的函数
def wrapper(): #第三层里不放参数
print('hello')
func() # 此处为调用要被装饰的函数
return wrapper
return fun1
return fun()
return pt2()
@pt1()
def shit():
print('shit')
#如果要装饰函数就需要取到最内层的wrapper
shit()
Py装饰器的更多相关文章
- py装饰器,生成器,迭代器
emmmmm....看了好久才能大概的看懂一点关于装饰器的内容...import sys # 引入sys模块import timeimport functoolsfrom functools impo ...
- Python基础2:反射、装饰器、JSON,接口
一.反射 最近接触到python的反射机制,遂记录下来已巩固.但是,笔者也是粗略的使用了__import__, getattr()函数而已.目前,笔者的理解是,反射可以使用户通过自定义输入来导入响应的 ...
- python使用装饰器@函数式化django开发
django是一个python web开发的框架.作为一个框架MVC的架构已经实现起来了.但是编码的时候你经常要进行进一步的抽象. AOP是一种称为面向切面的开发思想,意思是将部分功能代码在运行时动态 ...
- Django(五)母版继承、Cookie、视图装饰器等
大纲 一.内容回顾 补充:默认值 补充:命名空间 二.模板语言 1.母版继承 2.include 3.自定义simple_tag 三.Cookie Cookie 使用总结 四.视图 1.获取用户请求相 ...
- selenium 中装饰器作用
前面讲到unittest里面setUp可以在每次执行用例前执行,这样有效的减少了代码量,但是有个弊端,比如打开浏览器操作,每次执行用例时候都会重新打开,这样就会浪费很多时间.于是就想是不是可以只打开一 ...
- 就谈个py 的装饰器 decorator
很早很早就知道有这么个 装饰器的东西,叫的非常神秘. 包括c# 和 java 中都有这个东西, c#中叫做attribut 特性,java中叫做Annotation 注解,在偷偷学习c#教程的时候, ...
- py基础4--迭代器、装饰器、软件开发规范
本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1. 列表生成式,迭代器&生成器 列表生成式 我现在有个需求, ...
- Py修行路 python基础 (十)装饰器
装饰器 一.定义 装饰器:顾名思义,就是对某个东西起到装饰修饰的功能. python中的装饰器,其本质上就是一个python函数,它可以让其他函数在不需要任何代码变动的前提下增加额外功能.通俗理解就是 ...
- [原创]django+ldap实现单点登录(装饰器和缓存)
前言 参考本系列之前的文章,我们已经搭建了ldap并且可以通过django来操作ldap了,剩下的就是下游系统的接入了,现在的应用场景,我是分了2个层次,第一层次是统一认证,保证各个系统通过ldap来 ...
随机推荐
- 数字crawlergo动态爬虫结合长亭XRAY被动扫描
群里师傅分享了个挖洞的视频,搜了一下,大概就是基于这篇文章录的 https://xz.aliyun.com/t/7047 (小声哔哔一下,不得不说,阿里云先知社区和360酒仙桥六号部队公众号这两个地方 ...
- wordpress 后台富文本编辑器,添加图片发现无法左对齐,样式出现混乱
如上图所示,无法左对齐,但是左对齐的按钮全部是正确的,最后一点点排除,发现是因为这个词的影响,去掉就好了,原因不明,可能是这个词被当做某个方法执行了
- SQLServer之 Stuff和For xml path
示例 昨天遇到一个SQL Server的问题:需要写一个储存过程来处理几个表中的数据,最后问题出在我想将一个表的一个列的多行内容拼接成一行,比如表中有两列数据 : 类别 名称 AAA 企业1 AAA ...
- 神奇的 SQL 之擦肩而过 → 真的用到索引了吗
开心一刻 今天下班,骑着青桔电动车高高兴兴的哼着曲回家,感觉整个世界都是我的 刚到家门口,还未下车,老妈就气冲冲的走过来对我说道:"你表哥就比你大一岁,人家都买了奔驰了,50 多万!&quo ...
- 论文阅读LR LIO-SAM
Abstract 紧耦合lidar inertial里程计, 用smoothing和mapping. 1. Introduction 紧耦合lidar-inertial里程计. 紧耦合的lidar i ...
- Lombok注解-@SneakyThrows
@SneakyThrows注解的用途得从java的异常设计体系说起. java中我们常见的2类异常. 1.普通Exception类,也就是我们常说的受检异常或者Checked Exception. 2 ...
- 2.2.2 Sqoop2 基本架构
主要组件 1.Sqoop Client 定义了用户使用Sqoop的方式,包括客户端命令行CLI和浏览器两种方式,浏览器允许用户直接通过Http方式完成Sqoop的管理和数据的导出 2.Sqoop Se ...
- pxe过程和原理
pxe过程和原理 概要 远程安装和启动操作系统 网卡固件支持pxe的接口,一般是有基本的ip/udp协议栈,支持dhcp, tftp协议:bios中可以设置通过pxe启动操作系统 启动过程,大致如下: ...
- 关于.NET中的控制反转(二)- 依赖注入之 MEF
一.MEF是什么 Managed Extensibility Framework (MEF) 是用于创建可扩展的轻量级应用程序的库. 它让应用程序开发人员得以发现和使用扩展且无需配置. 它还让扩展开发 ...
- TCP三次握手(通俗易懂)
一--导读 前不久中国和外国RPEC协议的签订,标志着东亚自贸区的建立成功.现在韩国和日本要做贸易.日本一直监听着韩国总统的一举一动,但他又不会主动.(服务器的监听状态)只是被动的等着韩国总统先开口. ...