13、装饰器与迭代器

一、复习

储备知识1
def index(x,y):
   print(x,y)
​
def wrapper(*args,**kwargs):
   index(*args,**kwargs)  # index(1,2,z=3)
​
wrapper(1,2,z=3)
​
​
储备知识2
def outter():
   def wrapper():
       pass
​
储备知识3:
结论1:L-》E-》G-》B
结论2:名称空间的嵌套关系是在函数定义阶段扫描语法时生成的
​
储备知识4:
def outter():
   x = 111
   def wrapper():
       print(x)
   return wrapper
​
​
f=outter()  # f=函数wrapper的内存地址
​
def foo():
   x=222
   f()
​
foo()
​
​
储备知识5:为函数体传参的两种方案
方案一:
def wrapper(x):
   print(x)
​
wrapper(111)
wrapper(222)
​
​
方案二:
def outter(x):
   def wrapper():
       print(x)
​
   return wrapper
​
f = outter(111)  #f = 函数wrapper的内存地址
f()
​
f = outter(222)  #f = 函数wrapper的内存地址
f()
​

 

二、装饰器

"""
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)
​
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
​
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):
       res = func(*args,**kwargs)
       return res
   return wrapper
​
​
def sayhi(func):
   def wrapper(*args,**kwargs):
       print('hello')
       res = func(*args,**kwargs)
       return res
   return wrapper
​
def auth(func):
   def wrapper(*args,**kwargs):
       u = input('username>>>: ').strip()
       p = input("password>>>: ").strip()
       if u == 'egon' and p == '123':
           res = func(*args,**kwargs)
           return res
       else:
           print("认证失败")
   return wrapper
​
@auth
def index():
   print('index=========>')
​
index()

 

五、迭代器

"""
1 什么是迭代器
  迭代器指的是迭代取值的工具
  什么是迭代???
      迭代是一个重复的过程,但是每一次重复都是基于上一次结果而继续的
​
​
  # names = ['egon','tom','lili','jack','xxx']
  # msg = "hello world"
​
  dic = {'k1':111,'k2':2222,'k3':33333}
​
  def foo(xxx):
      i = 0
      while i < len(xxx):
          print(xxx[i])
          i += 1
​
  # foo(names)
  # foo(msg)
  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__()
​
​
print(len("abc"))  # "abc".__len__()
​
dic = {'k1':1111,'k2':2222,'k3':3333}
iter_dic = dic.__iter__()  # iter_dic=iter(dic)
​
print(iter_dic)
print(iter_dic.__next__())  # print(next(iter_dic))
print(iter_dic.__next__())
print(iter_dic.__next__())
# print(iter_dic.__next__()) # 报错
​
new_iter = dic.__iter__()
print(new_iter.__next__())
​
​
msg = "hello world"
iter_msg = msg.__iter__()
​
print(iter_msg.__next__())
print(iter_msg.__next__())
print(iter_msg.__next__())
print(iter_msg.__next__())
​
​
dic = {'k1': 1111, 'k2': 2222, 'k3': 3333,'k4':4444,'k5':5555}
​
iter_dic = iter(dic)
iter_dic.__next__()
print(iter_dic.__iter__().__iter__().__iter__() is iter_dic)
​
while True:
   try:
       print(next(iter_dic))
   except StopIteration:
       break
​
for x in dic:
   print(x)
​
​
​
​
例1:
dic = {'k1': 1111, 'k2': 2222, 'k3': 3333,'k4':4444,'k5':5555}
​
iter_dic = iter(dic)
for k in iter_dic:
   print(k)
print('='*50)
# iter_dic = iter(dic)
for k in iter_dic:
   print(k)
​
例2
with open('a.txt',mode='rt',encoding='utf-8') as f:
   for line in f:
       print(line)
   print('='*50)
   for line in f:
       print(line)
​
​
l = [1,2,3,4,5,6,7,8,9]
iter_l=iter(l)

 

六、自定义迭代器

​
yield可以返回多次值
​
def func():
   print('hello1')
   print('hello1')
   print('hello1')
   yield 111
   print('hello2')
   print('hello2')
   print('hello2')
   yield 222
   print('hello3')
   print('hello3')
   print('hello3')
   print('hello3')
   yield 333
   print('hello4')
   print('hello4')
   print('hello4')
   print('hello4')
函数内但凡出现yield语法,我们再调用函数就不会立即触发函数体代码运行,会返回一个生成器对象,生成器对象就是一种自定义的迭代器
​
g = func()
print(g)
g.__iter__()
g.__next__()
​
res=next(g)
print(res)
​
res=next(g)
print(res)
​
res=next(g)
print(res)
​
next(g)

 

posted @ 2021-10-09 20:35  谁笑  阅读(140)  评论(0)    收藏  举报