Python学习日记(九) 装饰器函数
1.import time
a.time.time()
获取到当前的时间,返回值为浮点型
import time
print(time.time()) #1565422783.6497557
b.time.sleep()
让程序执行到这个位置暂停一会
import time
start = time.time()
time.sleep(0.5)
print('hello world!')
end = time.time()
print(end - start) #0.5000286102294922
2.装饰器函数
开发原则:开放封闭原则
装饰器的作用:在不改变原函数的情况下,在函数的前后添加功能
装饰器的本质:闭包函数
当想要知道一个程序执行的时间
import time
start = time.time()
time.sleep(0.5)
print('hello world!')
end = time.time()
print(end - start) #0.5000286102294922
再将里面的功能单独拉出来变成一个函数
import time
def func():
time.sleep(0.5)
print('hello world!')
def timer(func):
start = time.time()
func()
end = time.time()
print(end - start)
timer(func) #hello world!
#0.5000286102294922
将timer变成一个简单的装饰器
import time
def func(): #被装饰的函数
time.sleep(0.5)
print('hello world!')
def timer(func): #装饰函数
def inner():
start = time.time()
func()
end = time.time()
print(end - start)
return inner #回传inner函数的内存地址
get_inner = timer(func) #后者得到的是inner的内存地址再赋值给get_inner
get_inner() #hello world!
#0.5000286102294922
执行步骤:
开放封闭原则:开放指的是对扩展开放,封闭指的是对修改封闭
语法糖:@装饰器函数名 可以替代下面的写法
装饰带一般参数且有返回值函数的装饰器
import time
def wrapper(f): #装饰器函数
def inner(x):
res = f(x)
return res
return inner
@wrapper #相当于 fuc = wrapper(fuc)
def fuc(var): #被装饰的函数
print(var,'Python')
return False
res = fuc('Hello')
print(res)
装饰带万能参数的函数装饰器
import time
def wrapper(f): #装饰器函数
def inner(*args,**kwargs):
start = time.time()
ret = f(*args,**kwargs)
end = time.time()
print(end - start)
return ret
return inner
@wrapper #相当于 fuc = wrapper(fuc)
def fuc(a,b,c,d,e = 5): #被装饰的函数
time.sleep(0.5)
print(a,b,c,d,e)
return e
print(fuc(1,2,3,4,'Python'))
总结:装饰器的模板
import time
def wrapper(f):
def inner(*args,**kwargs):
#在被装饰函数之前要做的事
res = f(*args,**kwargs)
#在被装饰函数之后要做的事
return res
return inner
@wrapper
# func = wrapper(func)
def func(): #被装饰的函数
return
ret = func()
print(ret)
查看函数信息的方法
def fuc(var):
''
print(var,'Python')
return False
print(fuc.__name__) #fuc 主要用于查看函数名
print(fuc.__doc__) #0123456789 主要用于查看函数的注释
我们在使用fuc()函数的时候实际上我们调用的是inner()函数,如果我们要在不修改原函数的前提下拿到原函数的信息,只需要将inner()函数变成一个装饰器:
def wrapper(f):
def inner(*args,**kwargs):
ret = f(*args,**kwargs)
return ret
return inner
@wrapper
def fuc():
print('Python')
return True
print(fuc())
print(fuc.__name__) #inner 这里调用的是inner函数
修改后:
from functools import wraps
def wrapper(f):
@wraps(f)
def inner(*args,**kwargs):
ret = f(*args,**kwargs)
return ret
return inner
@wrapper
def fuc():
print('Python')
return True
print(fuc())
print(fuc.__name__) #fuc 这里就改回调用的函数名是fuc
带参数的装饰器
如果许多函数都使用了同一个装饰器,那么它将需要一个布尔值作为参数来作为开关控制它们的使用
FLAGE = False
def wrapper_ctrl(flag):
def wrapper(fuc):
def inner(*args,**kwargs):
if flag:
print('装饰器已开启...')
ret = fuc()
return ret
else:
print('装饰器已关闭...')
return inner
return wrapper @wrapper_ctrl(FLAGE)
def function1():
print('aaaaaaa') @wrapper_ctrl(FLAGE)
def function2():
print('bbbbbbb') @wrapper_ctrl(FLAGE)
def function3():
print('ccccccc') function1() #装饰器已关闭...
function2() #装饰器已关闭...
function3() #装饰器已关闭...
多个装饰器装饰一个函数
def wrapper1(fuc): #2Step:fuc->f
def inner1(*args,**kwargs):
print('wrapper1在装饰该函数前要做的事...') #12Step:print
fuc(*args,**kwargs) #13Step:这里的fuc就是f 因为第二步已经传进来了
print('wrapper1在装饰该函数后要做的事...') #15Step:print
return inner1 #3Step:传回inner1 def wrapper2(fuc): #6Step:fuc->inner1
def inner2(*args,**kwargs):
print('wrapper2在装饰该函数前要做的事...') #10Step:print
fuc(*args,**kwargs) #11Step:这里的fuc()实际上是inner1()
print('wrapper2在装饰该函数后要做的事...') #16Step:print
return inner2 #7Step:返回inner2
@wrapper2 #5Step:f = wrapper2(f) 这里的f是inner1 即 f = wrapper2(inner1)
#8Step:f = inner2
@wrapper1 #1Step:f = wrapper1(f)
#4Step:f = inner1
#装饰器会找离它最近的函数 离这个函数最近的装饰器会先执行
def f():
print('abcdefg') #14Step:print
f() #9Step:这里调用的f()实际上是inner2() '''执行结果'''
# wrapper2在装饰该函数前要做的事...
# wrapper1在装饰该函数前要做的事...
# abcdefg
# wrapper1在装饰该函数后要做的事...
# wrapper2在装饰该函数后要做的事...
流程图:
3.和装饰器相关的案例
a.编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需输入用户名和密码
FLAG = False
def login(f):
def inner(*args,**kwargs):
global FLAG
if FLAG: #如果已经登入成功
f(*args,**kwargs)
else:
username = input('请输入用户名:')
password = input('请输入密码:')
if username.strip() == 'JANE' and password.strip() == '':
FLAG = True
print('登入成功!')
f(*args,**kwargs)
else:
print('登入失败!')
return inner
get_name('JANE')
get_ID()
b.编写装饰器,为多个函数加上记录调用功能,要求每次调用函数都将把被调用的函数写入文件
def log(f):
def inner(*args,**kwargs):
with open('log.txt',mode = 'a',encoding='utf-8') as fileStream:
fileStream.write(f.__name__ + '\n')
f(*args,**kwargs)
return inner
@log
def get_name():
print('Your username is JANE')
@log
def get_ID():
print('Your user ID is 110123')
get_ID()
get_name()
get_ID()
c.编写下载网页的函数,要求功能是:用户传入一个url,函数返回下载页面的结果
from urllib.request import urlopen
def get(url):
html = urlopen(url).read()
return html
ret = get('http://www.baidu.com')
print(ret)
#<bound method HTTPResponse.read of <http.client.HTTPResponse object at 0x00000000073BC860>>
d.为c编写装饰器,实现缓存网页内容的功能,主要功能:实现下载的页面存放于文件中,如果文件内有值(文件大小不为0),就优先从文件中读取网页内容,否则就去下载,然后存到文件中
import os
from urllib.request import urlopen
def cache(func):
def inner(*args,**kwargs):
if os.path.getsize('web_cache'): #如果不为0 就是True 从文件中找到源码
with open('web_cache','rb') as f:
return f.read()
ret = func(*args,**kwargs) #取得网页的源码
with open('web_cache','wb') as f:
f.write(b'*******' + ret) #若文件没有网页源码则写入新标志和源码
return ret
return inner
@cache
def get(url):
code = urlopen(url).read()
return code
end = get('http://www.baidu.com')
print(end)
end = get('http://www.baidu.com')
print(end)
end = get('http://www.baidu.com')
print(end)
Python学习日记(九) 装饰器函数的更多相关文章
- python学习日记(装饰器的补充)
如何返回被装饰函数的函数名及注释? 问题及实现 先看典型的装饰器: def wrapper(f):#装饰器函数,f是被装饰函数 def inner(*args,**kwargs): '''执行函数之前 ...
- Python学习笔记012——装饰器
1 装饰器 1.1装饰器定义 在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator). 1.2 装饰器分类 装饰器:函数装饰器,类装饰器,函数的装饰器,类的装饰器 装饰器:函数装饰函 ...
- python基础篇_004_装饰器函数
python装饰器函数 1.装饰器函数引导 功能:计算函数执行时长 import time """ 方式一: 函数首位添加时间,差值就是函数执行时间 缺点:每个函数都要加 ...
- python学习笔记:装饰器2
python的装饰器本质是函数,为了不改变装饰目标函数内部代码而增加额外功能而存在 一.一般装饰函数实例: import datetime def func_name(func):#定义一个装饰函数, ...
- Python学习——迭代器&生成器&装饰器
一.迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素.迭代器仅 ...
- Python学习系列之装饰器
装饰器的作用 装饰器用于装饰某个函数.方法或者类,它可以让这个函数执行之前或者执行之后做一些操作 手工实现一个装饰器 def outer(some_func): #装饰器 $1 def inner() ...
- python学习-day20、装饰器【图片缺失可看】印象笔记博客备份
前言: 装饰器用于装饰某些函数或者方法,或者类.可以在函数执行之前或者执行之后,执行一些自定义的操作. 1.定义:装饰器就是一个函数,为新定义的函数.把原函数嵌套到新函数里面.以后就可以在执行新函数的 ...
- python学习笔记(五):装饰器、生成器、内置函数、json
一.装饰器 装饰器,这个器就是函数的意思,连起来,就是装饰函数,装饰器本身也是一个函数,它的作用是用来给其他函数添加新功能,比如说,我以前写了很多代码,系统已经上线了,但是性能比较不好,现在想把程序里 ...
- python学习笔记之装饰器、生成器、内置函数、json(五)
一.装饰器 装饰器,这个器就是函数的意思,连起来,就是装饰函数,装饰器本身也是一个函数,它的作用是用来给其他函数添加新功能比如说,我以前写了很多代码,系统已经上线了,但是性能比较不好,现在想把程序里面 ...
随机推荐
- [转]小D课堂 - 零基础入门SpringBoot2.X到实战_汇总
原文地址:https://www.cnblogs.com/wangjunwei/p/11392825.html 第1节零基础快速入门SpringBoot2.0 小D课堂 - 零基础入门SpringBo ...
- 如何查看window 7/window 8 等系统 的激活状态?
http://www.officezhushou.com/office-key/ Office激活密钥 Win+R 输入: slmgr.vbs -dlv 显示:最为详尽的激活信息,包括:激活ID. ...
- python 把带小数的浮点型字符串转换为整数的解决方案
以下内容在python中完全可以接受: 将整数的字符串表示形式传递给 int 将float的字符串表示形式传递给 float 但是,如果你将float型的字符串传递给int将会得到错误. >&g ...
- LeetCode_447. Number of Boomerangs
447. Number of Boomerangs Easy Given n points in the plane that are all pairwise distinct, a "b ...
- jxls:用jx:if实现字典值格式化
用JXLS导出excel非常方便,但是我们往往需要把字典值转为中文名称,例如1转为男,这个时候就需要用到jx:if来完成. 请见下图: jx:if(condition="obj.way==1 ...
- 创建slackapp prometheus告警发到slack
创建slackapp: https://blog.walterlv.com/post/slack-api-starter-incoming-webhooks.html#%E5%88%9B%E5%BB% ...
- 监听微信、支付宝等移动app及浏览器的返回、后退、上一页按钮的事件方法
在实际的应用中,我们常常需要实现在移动app和浏览器中点击返回.后退.上一页等按钮实现自己的关闭页面.调整到指定页面或执行一些其它操作的 需求,那在代码中怎样监听当点击微信.支付宝.百度糯米.百度钱包 ...
- [LeetCode] 844. Backspace String Compare 退格字符串比较
Given two strings S and T, return if they are equal when both are typed into empty text editors. # m ...
- 最新 识装java校招面经 (含整理过的面试题大全)
从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿. 识装等10家互联网公司的校招Offer,因为某些自身原因最终选择了 识装.6.7月主要是做系统复习.项目复盘.LeetCo ...
- SpringBoot系列教程web篇之Thymeleaf环境搭建
上一篇博文介绍了如何使用Freemaker引擎搭建web项目,这一篇我们则看一下另外一个常见的页面渲染引擎Thymeleaf如何搭建一个web项目 推荐结合Freemaker博文一起查看,效果更佳 1 ...