11-生成器

一、如何得到自定义的迭代器(生成器)

在函数内一旦存在yield关键字,调用函数并不会执行函数体代码

会返回一个生成器对象,生成器即自定义的迭代器

def func():
    print('第一次')
    yield 1
    print('第二次')
    yield 2
    print('第三次')
    yield 3
    print('第四次')


g=func()              # 此时并不运行函数体代码
print(g)              # <generator object func at 0x000001D009181740>
# 生成器就是迭代器
# g.__iter__()          均可调用
# g.__next__()

# next()或g.__next__ 会触发函数体代码的运行,然后遇到yield停下来,将yield后的值
# 当做本次调用的结果返回
res1=g.__next__()             # 打印第一次
print(res1)                   # 1

res2=g.__next__()             # 打印第二次
print(res2)                   # 2

res3=g.__next__()             # 打印第三次
print(res3)                   # 3

res4=g.__next__()             # 打印第四次,并抛出异常StopIteration

二、应用案例

def my_range(start,end=None,step=1):

    # 满足 range(5)---》0 1 2 3 4 的情况
    if end is None:
        output = 0
        while output < start:
            yield output
            output += step
    else:

    # 满足 range(0,5,2) 设定步长输出
        if step > 0:
            while start < end:
                yield start
                start += step

    # 满足range(5,0,-1) 步长为负时,逆走
        if step < 0:
            while start > end:
                yield start
                start += step

测试:

# 测试:
for i in my_range(5,0,-2):
    print(i,end=" ")

print("")

for i in range(5,0,-2):
    print(i,end=" ")

三、yield表达式 

3.1 yield表达式介绍

一般形式:x = yield 返回值

使用 g.send(“xxx”)的方式给x传参,并且send在传参后自带next()功能

但一个生成器开始时,需要进行初始化(g.send(None) 或 next(g))。若不初始化,将会有以下报错:

  

 3.2 yield表达式的使用案例

def dog(name):
    food_list=[]
    print('道哥%s准备吃东西啦...' %name)
    while True:
        # x拿到的是yield接收到的值
        x = yield food_list # x = '肉包子'
        print('道哥%s吃了 %s' %(name,x))
        food_list.append(x) # ['一根骨头','肉包子']

g=dog('alex')
res=g.send(None)  # next(g)
print(res)        # []

res=g.send('一根骨头')
print(res)        # ['一根骨头']

res=g.send('肉包子')
print(res)       # ['一根骨头', '肉包子']

g.close()
g.send('1111')  # 关闭之后无法传值 StopIteration

四、总结yield

有了yield关键字,我们就有了一种自定义迭代器的实现方式。yield可以用于返回值,但不同于return。
函数一旦遇到return就结束了,而yield可以保存函数的运行状态挂起函数,用来返回多次值

有了yield表达式,我们可以使函数的运行状态挂起,随时待命,等待我们再次传值给他。
原文地址:https://www.cnblogs.com/zhubincheng/p/12562447.html