## 带参装饰器 ```python 装饰器为被装饰的函数添加新功能,需要外界参数 #outer参数固定一个,就是func #inner参数固定和被装饰的参数固定,也不能添加新参数 #可以借助函数的嵌套定义,外层给内层传参 def wrap(info):#info就是需要的外界参数 def outer(func): def inner (*args,**kwargs): 新功能 res=func(*args,**kwargs) return res return inner return outer @wrap("外部参数") #系统wraps带参装饰器:改变inner的假指向,本质外界使用的还是inner,但是打印显示的是wraps中的函数 from functools import wraps def outer(func): @wraps(func) def inner(*args, **kwargs): res = func(*args, **kwargs) return res return inner @outer def fn(): pass ``` ## 迭代器 ```python 迭代器对象:可以不依赖取值容器,有__next__方法的对象就是迭代器对象,迭代器对象依赖__next__()方法取值 可迭代对象:可以通过某种方法得到迭代器对象,有__iter__()方法的对象就是可迭代对象,可迭代对象通过__iter__()方法得到迭代器对象 迭代器优点:可以不依赖索引取值, 缺点:只能从前往后取值 ``` ## for循环迭代器: ```python 直接用while True循环在迭代器对象中通过__next__()取值,终究会有取空的时候,取空再取值,报stopIteration异常 ls = [3, 1, 2, 3, 5] iterator = ls.__iter__() while True try: print(iterator.__next__()) except StopIteration: break #for循环就是while取迭代器对象的封装 for循环迭代器的工作原理:for v in obj:pass 1,获取obj__iter__()的结果,得到要操作的迭代器对象 2,迭代器对象通过__next__()方法进行取值,依次将当前循环的取值结果赋值给v 3,当取值抛异常,自动处理StopIteration异常结束取值循环 ``` ## 枚举对象: ```python 给迭代器对象及迭代器对象添加索引 s="abc" for v in enumerate(s): print(v)#(0 ,'a') | (1 ,'b') | (2 ,'c') ``` ## 生成器 ```python 生成器:自定义的迭代器对象 就是用函数语法来声明生成器,用yield关键字取代return关键字来返回值,参数没有变化 总结:有yield关键字的函数,函数名()不是调用函数,而是生成得到生成器对象,生成器对象就是迭代器对象,可以通过__next__进行取值 执行流程: def fn(): yield 1 yield 2 yield 3 obj=fn() #生成一次迭代器对象,赋值给obj obj.__next__()#从开始往下执行,遇到第一个yield停止,拿到yield的返回值 obj__next__()#从上一次停止的yield往下执行,再遇到yield停止,拿到当前停止的yield返回值 #依此类推,直到无法获得下一个yield,抛StopIteration异常 #可以被for循环遍历: for v in fn(): print v 案例: def jiecheng(): ji=1 count=1 while True: ji*=count yield ji count+=1 obj=jiecheng() print(obj.__next__()) print(obj.__next__()) print(obj.__next__()) print(obj.__next__()) # 可以无限取 案例2: def jiecheng_num(num): ji=1 for i in range(1,num+1): ji*=1 yield ji obj = jiecheng_num(3) print(obj.__next__()) print(obj.__next__()) print(obj.__next__()) print(obj.__next__()) # 有异常了 for v in jiecheng_num(5): print(v) # 会自动处理异常停止 ```