## 带参装饰器
```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) # 会自动处理异常停止
```