1、什么是装饰器
装饰器就是装饰别人的工具,具体是指为被装饰者添加新功能
装饰器-》函数
被装饰者-》函数
2、为何要用装饰器
装饰器的核心思想:(开放封闭原则)
在不修改被装饰者源代码以及调用方式的前提下,为被装饰者添加新功能
3、如何实现装饰器
可以用闭包函数去实现装饰器
被装饰者
import time
def index():
print('welcome to index page')
time.sleep(3)
index()
方案一:问题-》修改了被装饰者的源代码
import time
def index():
start = time.time()
print('welcome to index page')
time.sleep(3)
stop = time.time()
print(stop - start)
index()
方案二:问题-》会造成代码冗余
import time
def index():
print('welcome to index page')
time.sleep(3)
start = time.time()
index()
stop = time.time()
print(stop -start)
start = time.time()
index()
stop = time.time()
print(stop -start)
# 方案三:问题-》修改了被装饰对象的调用方式
import time
def index():
print('welcome to index page')
time.sleep(3)
def wrapper(func):
start = time.time()
func()
stop = time.time()
print(stop -start)
wrapper(index)
# 方案四:我们用wrapper函数赋值给原函数名index,wrapper应该与原函数保持一致,但是现在的问题是不一致
import time
def index():
print('welcome to index page')
time.sleep(3)
def outter(func): # func = 最原始那个index函数的内存地址
def wrapper():
start = time.time()
func()
stop = time.time()
print(stop -start)
return wrapper
index = outter(index) # f=outter(最原始那个index函数的内存地址)
# f=函数wrapper的内存地址
# print(f)
index()
方案四:让wrapper的参数与返回值与被装饰者保持一致
import time
def index(x,y,z):
print('welcome to index page',x,y)
time.sleep(3)
return 123
def outter(func): # func = 最原始那个index函数的内存地址
def wrapper(*args,**kwargs):
start = time.time()
res = func(*args,**kwargs)
stop = time.time()
print(stop -start)
return res
return wrapper
index = outter(index) # f=outter(最原始那个index函数的内存地址)
# f=函数wrapper的内存地址
res = index(111,222,333) # res = wrapper(111,222,333)
print(res)
二、装饰器语法糖
# 装饰器语法糖:在不修改源代码情况下,为其新增功能称之为装饰器语法糖。
import time
from functools import wraps # wraps:别人写好的装饰器模块
def outter(func):
@wraps(func)
def wrapper(*args, **kwargs): # 可变长参数
start = time.time()
res = func(*args, **kwargs)
stop = time.time()
print(stop - start)
return res
return wrapper
@outter # index = outter(index)
def index(x, y, z):
"""index函数的文档注释"""
print('welcome to index page', x, y)
time.sleep(3)
return 123
# res = index(111, 222, 333)
# print(res)
# print(index)
help(index)
三、装饰器模板
# 装饰器模板
def outter(func):
def wrapper(*args,**kwargs):
print('hello')
res = func(*args,**kwargs)
return res
return wrapper
@outter
def index():
print('index=========>')
index() # 调用
# 案例
def auth(func):
def wrapper(*args,**kwargs):
username = input('username>>>: ').strip()
password = input("password>>>: ").strip()
if username == 'meng' and password == '123':
res = func(*args,**kwargs)
return res
else:
print("认证失败")
return wrapper
@auth
def index():
print('index=========>')
index()
四、迭代器
1、什么是迭代器
迭代器指的是迭代取值的工具
什么是迭代???
迭代是一个重复的过程,但是每一次重复都是基于上一次结果而继续的
dic = {'k1':111,'k2':2222,'k3':33333}
def foo(xxx):
i = 0
while i < len(xxx):
print(xxx[i])
i += 1
foo(dic)
2、为何要用迭代器
1.为了找到一种统一迭代取值方案(适用于str、list、tuple、dict、set,文件对象)
2.节省内存
3、如何用迭代器
可迭代的对象iterable:
内置有__iter__方法的对象(str、list、tuple、dict、set,文件对象)
迭代器对象iterator:
内置有__iter__方法:生成一个可迭代对象
内置有__next__方法:取值
# 可迭代对象:
"abc".__iter__()
[1,23].__iter__()
(1,2,3).__iter__()
{'k1':111}.__iter__()
{1,2,3}.__iter__()
f = open('a.txt',mode='wt')
f.__iter__()
案例1:代码冗余
dic = {'k1':1111,'k2':2222,'k3':3333}
iter_dic = dic.__iter__() # iter_dic=iter(dic) 变成一个可迭代对象
print(iter_dic.__next__()) # print(next(iter_dic))
print(iter_dic.__next__())
print(iter_dic.__next__()) # 只能去列表的3个值,取完再取会报错。
# print(iter_dic.__next__()) # 报错
new_iter = dic.__iter__() # 从新取只能在新建一个可迭代对象
print(new_iter.__next__()) # 在从新取值
案例2:用捕捉异常让代码继续执行
dic = {'k1': 1111, 'k2': 2222, 'k3': 3333,'k4':4444,'k5':5555}
def did():
iter_dic = iter(dic)
while True:
try:
print(next(iter_dic))
except StopIteration:
break
did()
for x in dic: # for循环原理:迭代器对象
print(x)
自定义迭代器
# yield可以返回多次值
def func():
print('hello1')
print('hello1')
yield 111
print('hello2')
print('hello2')
yield 222
print('hello3')
print('hello3')
yield 333
print('hello4')
print('hello4')
# 函数内但凡出现yield语法,我们再调用函数就不会立即触发函数体代码运行,会返回一个生成器对象,生成器对象就是一种自定义的迭代器
g = func()
print(g) # 会打印出111