Python Day14:带参装饰器、生成器、迭代器、for循环迭代器、枚举

## 带参装饰器

```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)  # 会自动处理异常停止
    
```
原文地址:https://www.cnblogs.com/huhongpeng/p/10808313.html