Day 14:装饰器
01 今日内容大纲
- 90,自我
- 调整自己,适当听取一些其他人的意见
- 承受压力的能力一定要有所提高
02 昨日内容回顾
- 匿名函数:一句话函数,多与内置函数,列表推导式结合
- 内置函数:加key!!!! min,max,sorted,map,reduce,filter
- 闭包:
- 内层函数对外层函数的非全局变量的使用
- 一定要存在于嵌套函数中
- 作用:保证数据安全,自由变量不会在内存中消失,而且全局还引用不到
03 今日内容
-
开放封闭原则:
# 装饰器:装饰,装修,房子可以住,如果装修,不影响你住,畏怯体验更加,让生活增加了很多功能:洗澡,看电视,沙发
# 器:工具
# 开放封闭原则:
# 开放:对代码的拓展是完全开放的,更新地图,加新枪,等等
# 封闭:对源码的修改是封闭的,闪躲用q.就是一个功能,一个函数,别人赤手空拳打你,机枪扫射你,扔雷....这些功能不会改变 -
装饰器初识:
# 装饰器:完全遵循开放封闭原则.
# 装饰器:在不改变原函数代码以及调用方式的前提下,为其增加新的功能
# 装饰器就是一个函数-
版本一:写一些代码,测试一下index函数的执行效率
import time
def index():
'''有很多代码'''
time.sleep(2)#模拟网络延迟或代码效率
print('欢迎登陆博客园首页')def dairy():
'''有很多代码'''
time.sleep(2)#模拟网络延迟或者代码效率
print('欢迎登陆日记页面')print(time.time()) #输出格林威治时间
print(111)
time.sleep(3)
print(222)版本1有问题: 如果测试别人的代码必须复制粘贴
import time
start_time = time.time()
index()
end_time = time.time()
print(end_time-start_time)start_time = time.time()
dairy()
end_time = time.time()
print(end_time-start_time) -
版本二:利用函数,解决代码重复使用的问题
import time
def index():
'''有很多代码'''
time.sleep(2)#模拟网络延迟或代码效率
print('欢迎登陆博客园首页')def dairy():
'''有很多代码'''
time.sleep(2)#模拟网络延迟或者代码效率
print('欢迎登陆日记页面')def timer(f):
start_time = time.time()
f()
end_time = time.time()
print(f'测试本函数的执行效率为{end_time-start_time}')
timer(index)
timer(dairy)
# 版本2还是有问题:原来index函数源码没有变化,给原函数添加一个新的功能测试原函数的执行效率的功能
# 满足开放封闭原则么?不满足,原函数的调用方式改变了 -
版本三:不能改变原函数的调用方式
import time
def index():
'''有很多代码'''
time.sleep(2)#模拟网络延迟或代码效率
print('欢迎登陆博客园首页')def timer(f): #f = index
def inner():
start_time = time.time()
f() #index()
end_time = time.time()
print(f'测试本函数的执行效率为{end_time - start_time}')
return innerret = timer(index) # ret = timer(index)=inner
ret() #inner() -
版本四:具体研究
import time
def index():
'''有很多代码.....'''
time.sleep(2) # 模拟的网络延迟或者代码效率
print('欢迎登录博客园首页')def timmer(f):
f = index
# f = <function index at 0x0000023BA3E8A268>
def inner():
start_time = time.time()
f()
end_time = time.time()
print(f'测试本函数的执行效率{end_time-start_time}')
return innerindex = timmer(index)
index() -
版本五:python做了一个优化,提出了语法糖的概念.标准版的解释器
import time
# # timmer 装饰器
def timmer(f):
# f = index
# f = <function index at 0x0000023BA3E8A268>
def inner():
start_time = time.time()
f() #index()
end_time = time.time()
print(f'测试本函数的执行效率{end_time-start_time}')
return inner@timmer #index = timmer(index)
def index():
'''有很多代码.....'''
time.sleep(2) # 模拟的网络延迟或者代码效率
print('欢迎登录博客园首页')
index() #inner()def dariy():
'''有很多代码.....'''
time.sleep(3) # 模拟的网络延迟或者代码效率
print('欢迎登录日记页面')
dariy() -
版本六:被装饰函数带返回值
import time
# timmer装饰器
def timmer(f):
# f = index
def inner():
start_time = time.time()
# print(f'这是个f():{f()}!!!') # index()
r = f()
end_time = time.time()
print(f'测试本函数的执行效率{end_time-start_time}')
return r
return inner@timmer # index = timmer(index)
def index():
'''有很多代码.....'''
time.sleep(0.6) # 模拟的网络延迟或者代码效率
print('欢迎登录博客园首页')
return 666
ret = index() #inner()
print(ret)
# 加上装饰器不应该改变原函数的返回值,所以666应该返回给下面的ret
# 但是下面的ret实际是接收的inner()的返回值,而666返回给的是装饰器里面的f(),也就是r,我们现在要解决的问题就是将r给inner()的返回值 -
版本七:被装饰函数带参数
import time
# timmer装饰器
def timmer(f):
# f = index
def inner(args,**kwargs):
# 函数的定义: 聚合 args = ('李舒淇',18)
start_time = time.time()
# print(f'这是个f():{f()}!!!') # index()
r = f(args,**kwargs)
# 函数的执行: 打散:f(args) --> f(('李舒淇',18)) --> f('李舒淇',18)
end_time = time.time()
print(f'测试本函数的执行效率{end_time-start_time}')
return r
return inner@timmer # index = timmer(index)
def index(name):
'''有很多代码.....'''
time.sleep(2) # 模拟的网络延迟或者代码效率
print(f'欢迎{name}登录博客园首页')
return 666
ret = index('纳钦') # inner('纳钦')
print(ret)@timmer
def dariy(name,age):
'''有很多代码.....'''
time.sleep(2) # 模拟的网络延迟或者代码效率
print(f'欢迎{age}岁{name}登录日记页面')
dariy('李舒淇',18) # inner('李舒淇',18)
-
-
标准版装饰器代码:
# 标准版
def wrapper(f):
def inner(args,**kwargs):
'''添加额外的功能:执行被装饰函数之前的操作'''
r = f(args,**kwargs)
''''添加额外的功能:执行被装饰函数之后的操作'''
return r
return inner -
装饰器的应用:
# 装饰器的应用:登录认证
# 这周的周末作业:模拟博客园登录的作业。装饰器的认证功能。def login():
pass
def register():
pass
status_dict = {
'username':None,
'status': False
}
def auth(f):
'''你的装饰器完成:访问被装饰函数之前,写一个三次登录认证的功能。
登录成功:让其访问被装饰得函数,登录没有成功,不让访问。'''
def inner(args,**kwargs):
'''访问函数之前的操作,功能'''
if status_dict['status']:
r = f(args,kwargs)
'''访问函数之后的操作,功能'''
return r
else:
username = input('请输入用户名').strip()
password = input('请输入密码').strip()
if username == '刘译蓬'and password =='daaipengge123':
status_dict['username'] = username
status_dict['status'] = True
r = f(*args,kwargs)
return r
else:
print('登录失败')
return inner
@auth
def article():
print('欢迎访问文章页面')
@auth
def comment():
print('欢迎访问评论页面')
@auth
def dariy():
print('欢迎访问日记页面')article()
comment()
dariy()
04 今日总结
- 装饰器:完美的呈现了开放(拓展功能)封闭(被装饰函数)原则.装饰器的本质就是闭包(自由变量f)
- def wrapper(f):
def inner(args,**kwargs):
'''执行被装饰函数之前的操作,功能'''
r = f(args,**kwargs)
'''执行被装饰函数之后的操作,功能'''
return r
return inner
05 预习内容
浙公网安备 33010602011771号