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 inner ret = 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 inner index = 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 预习内容