day 11 - 1 装饰器
装饰器
装饰器形成的过程:最简单的装饰器——有返回值的——有一个参数——万能参数
装饰器的作用:不想修改函数的调用方式 但是还想在原来的函数前后添加功能
原则:开放封闭原则
语法糖:@装饰器函数名
装饰器的固定模式
原则:开放封闭原则
开放:对扩展是开放的
封闭:对修改是封闭的
首先我们来逐步实现这么一个功能吧
计算代码运行的时间
#先来看下需要的组件
import time #time 模块 time.time() #获取当前时间
time.sleep(5) #让程序睡眠多少时间 print(time.time()) #来试下
我们来写一个可以计算时间的函数
def func():
start=time.time()
time.sleep(0.1) #时间太短 系统会显示 0.0,所以我们让他休眠 0.1s
print("计算程序执行的时间")
end=time.time()
print(end-start) func()
但是这里有一个问题:如果要计算很多函数的运行时间,那不是要在函数中都加上几行计算的代码,这显然是不可行的,一般写好的没问题的函数,是不会去对它进行修改,而且还很麻烦
所以这里我们写一个计算时间的函数独立出来
def times(f):
start=time.time()
time.sleep(0.1)
f()
end=time.time()
print(end-start) def func():
print("计算程序执行的时间") def func2():
print(time.sleep(5)) times(func)
times(func2)
但是这样貌似还有一个问题,我要计算时间的函数都要调用 times() 函数,这样其实是很麻烦的
最终还是要调用 func() 就可以计算运行时间,就是说你调用的是 func() 其实调用的 times() 这就很完美了
接着我们来了解下装饰器吧,解决这样的问题
先来写一个简单的装饰器
#一个简单的装饰器
import time
def func():
time.sleep(0.1)
print('你好,世界') def timmer(f): #装饰器函数
def inner():
start = time.time()
f() #被装饰的函数
end = time.time()
print(end - start)
return inner func = timmer(func) #通过这一步就可以使用 func 调用 timmer 了
func()
我们这里做的事情就是:在不想修改函数的调用方式的情况下 但还想在原来的函数前后添加功能
接着我们来看另一个甜甜的东西——语法糖
import time def timmer(f): #装饰器函数
def inner():
start = time.time()
time.sleep(0.1)
f() #被装饰的函数
end = time.time()
print(end - start)
return inner @timmer #语法糖 替代下面 func = timmer(func) 这句话
def func():
time.sleep(0.1)
print('你好,世界') #func = timmer(func) #通过这一步就可以使用 func 调用 timmer 了
func()
然后我们来看接收返回值的装饰器
import time def timmer(f): #装饰器函数
def inner():
start=time.time()
time.sleep(0.1)
ret = f() #被装饰的函数
end=time.time()
print(end-start)
return ret #接收 func() 函数的返回值
return inner #这个地方要穿函数的名字 而不是加括号 @timmer #语法糖 替代下面 func = timmer(func) 这句话
def func():
print('你好,世界')
return 'Hello' print(func()) #返回值打印 返回值为:Hello
最后我们来看带参数的装饰器,一个参数与万能参数是一样的,只是参数的不同罢了
#一个参数的装饰器
import time def timmer(f): #装饰器函数
def inner(a): #3.给 inner() 加上参数
start=time.time()
time.sleep(0.1)
ret = f(a) #4.由于 inner() 把参数传给了 f(),所以 f() 也要加上参数,最后测试传值
end=time.time()
print(end-start)
return ret #接收 func() 函数的返回值
return inner @timmer #语法糖 替代下面 func = timmer(func) 这句话
def func(a): #2.这里也要加上参数,由于执行 func 时,实际执行的 inner(),所以 inner() 也要加上参数
print("计算程序执行的时间",a)
return 'Hello' print(func("")) #1.加入参数 #输出结果
'''
计算程序执行的时间 123
0.10937380790710449
Hello
'''
###万能参数的装饰器
#可以看出 只是在 a 的位置更换了 *args **kwargs 来接收参数
import time def timmer(f):
def inner(*args,**kwargs):
start=time.time()
time.sleep(0.1)
ret = f(*args,**kwargs)
end=time.time()
print(end-start)
return ret
return inner @timmer
def func(*args,**kwargs):
print("计算程序执行的时间",args,kwargs) #2. 就是这个位置的 kwargs,如果写了,打印时会出现一个 ' {} ' 空字典,并不会报错
return 'Hello' print(func('','','',k=100)) #1. 不需要关键字传参时,kwargs 可以不写 #输出结果
'''
计算程序执行的时间 ('1', '2', '3') {'k': 100}
0.1093745231628418
Hello
'''
好了,以上就是我们对于装饰器完善的最终结果了
装饰器的固定模式
def wrapper(f): #装饰器函数,f是被装饰的函数
def inner(*args,**kwargs): #定义一个内置函数,且和下面统级别的返回值名字一致且不加括号
#动态参数一定要原封不动的传给 被装饰的函数 f()
'''在被装饰函数之前要做的事'''
ret = f(*args,**kwargs) #被装饰的函数 函数执行完的返回值要原封不动传给 return
'''在被装饰函数之后要做的事'''
return ret
return inner @wrapper #语法糖 @装饰器函数名 等价于 func = wrapper(func)
def func(a,b): #被装饰的函数
time.sleep(0.01)
print('你好:世界',a,b)
return '新年好'
#print(func(23,45)) #接收返回值
ret = func(23,45) #接收返回值
print(ret)
day 11 - 1 装饰器的更多相关文章
- day 11 - 2 装饰器练习
1.编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件)要求登录成功一次,后续的函数都无需再输入用户名和密码 FLAG = False def login(func): def inner ...
- Django-website 程序案例系列-11 验证装饰器
FBV装饰器: def auth(func): #装饰器函数 def inner(request, *args, **kwargs): v = request.COOKIES.get('usernam ...
- Python学习:11.Python装饰器讲解(二)
回顾 上一节我们进行了Python简单装饰器的讲解,但是python的装饰器还有一部分高级的使用方式,这一节就针对python装饰器高级部分进行讲解. 为一个函数添加多个装饰器 今天,老板又交给你一个 ...
- Day 11:函数装饰器
在说装饰器前,先说一个东西,再Python里,有一个 一切皆对象,一切皆变量. 例: def hello(name="sunjinyao"): return "hi &q ...
- 总结了11条,我对Python 装饰器的理解
对于每一个学习 Python 的同学,想必对 @ 符号一定不陌生了,正如你所知, @ 符号是装饰器的语法糖,@符号后面的函数就是我们本文的主角:装饰器. 装饰器放在一个函数开始定义的地方,它就像一顶帽 ...
- python 装饰器、递归原理、模块导入方式
1.装饰器原理 def f1(arg): print '验证' arg() def func(): print ' #.将被调用函数封装到另外一个函数 func = f1(func) #.对原函数重新 ...
- Python核心编程 | 装饰器
装饰器是程序开发的基础知识,用好装饰器,在程序开发中能够提高效率 它可以在不需要修改每个函数内部代码的情况下,为多个函数添加附加功能,如权限验证,log日志等 涉及点: 1.先梳理一下 ...
- 面向对象程序设计(OOP设计模式)-结构型模式之装饰器模式的应用与实现
课程名称:程序设计方法学 实验4:OOP设计模式-结构型模式的应用与实现 时间:2015年11月18日星期三,第3.4节 地点:理1#208 一.实验目的 加深对结构型设计模式的理解以及在开发中的实际 ...
- Python小白学习之函数装饰器
装饰器 2018-10-25 13:49:37 装饰器从字面意思就是用来装饰的,在函数可以理解为:在函数中,我们不想影响原来的函数功能,又想给函数添加新的功能,这时候我们就用到了装饰器. 一般函数操作 ...
随机推荐
- Vue的简单入门
Vue的简单入门 一.什么是Vue? vue.js也一个渐进式JavaScript框架,可以独立完成前后端分离式web项目 渐进式:vue可以从小到控制页面中的一个变量后到页面中一块内容再到整个页面, ...
- python自动化开发-[第十一天]-Mysql
今日概要: 1.初识mysql 2.MySQL的增删改查 3.主键.外键 4.组合和分组 一.数据库的由来 1.什么是数据库? 数据的仓库,在ATM,购物车中存储数据为目录,称为数据库 1.数据以表格 ...
- BZOJ4627 前缀和 + 权值线段树
https://www.lydsy.com/JudgeOnline/problem.php?id=4627 题意:求序列中和在L到R之间的字串种数. 要求的是和的范围,我们可以考虑先求一个前缀和pre ...
- Advertising.csv
TV,radio,newspaper,sales1,230.1,37.8,69.2,22.12,44.5,39.3,45.1,10.43,17.2,45.9,69.3,9.34,151.5,41.3, ...
- MyBatis-${}与#{}
一.看两种取值的效果 <select id="selectMyUserIdAndAge" resultType="myUser"> select * ...
- 设计模式---数据结构模式之组合模式(Composite)
前提:数据结构模式 常常有一些组建在内部具有特定的数据结构,如果让客户程序依赖这些特定的数据结构,将极大的破坏组件的复用.这时候,将这些数据结构封装在内部,在外部提供统一的接口,来实现与特定数据结构无 ...
- ubuntu 14.04中安装 ruby on rails 环境
环境:在win7 上Vmware虚拟机环境中安装的ubuntu 14.04 1. bundle install 时,报json错误可以看出是在安装nokogiri时遇到了问题,此时执行 sudo ap ...
- SQLyog远程连接腾讯云服务器数据库Mysql遇到的坑
首先说明我的数据库是安装在云服务器上,不是专业的数据库服务器,没错就是10块钱包月的. 然后觉得使用SQLyog远程维护数据库比较方面,可是怎么都登录不上去. 下面分析原因: 1.安全组是否放过了访问 ...
- sqlyog创建数据库表关系图
作为一个后台前端,数据库,需求分析,运维,PPT全包的码农来说.uml建模不存在的,对不起我没有时间,就用sqlyog拉几个你看看吧.看的懂的一眼就看清了,看不懂的整再好也是白瞎. 第一步:选择增强工 ...
- Maccms8.x 命令执行漏洞分析
下载链接https://share.weiyun.com/23802397ed25681ad45c112bf34cc6db 首先打开Index.php $m = be('get','m'); m参数获 ...