生成器send函数

一、生成器说明

  

  1、生成器是一个特殊的迭代器。

  因为它既没有【__iter__】方法,也没有【__next__】方法。

  

  2、示例1:使用while循环去遍历自定义的生成器对象

def create_num(all_nums):
    a, b = 0, 1
    current_num = 0
    while current_num < all_nums:
        yield a
        a, b = b, a+b
        current_num += 1


obj = create_num(10)

while True:
    try:
        ret = next(obj)
        print(ret)
    except Exception as ret:
        break
View Code

运行结果:

0

1

1

3

5

8

13

21

34

3、示例2:得到生成器的返回值,则调用异常类中【value】可查看。

def create_num(all_nums):
    a, b = 0, 1
    current_num = 0
    while current_num < all_nums:
        yield a
        a, b = b, a+b
        current_num += 1
    return "-----ok-----"


obj = create_num(10)

while True:
    try:
        ret = next(obj)
        print(ret)
    except Exception as ret:
        print(ret.value)
        break
View Code

运行结果:

0

1

1

3

5

8

13

21

34

-----ok-----

  

二、send函数

  1、说明:除了使用【next】函数可以启动生成器还可以使用【send】函数启动。

  2、特点:  启动生成器后,并且发送数据至生成器中

  3、send函数的应用场景:当生成器生成一个新的值时,通过send函数传递一个新的参考值,然后根据这个参考值去做事情。

  4、语法:生成器对象.send(参数)

  5、查看send函数的执行流程:

    第一次调用【next】函数时,程序执行到【yield】关键字处暂停,并将局部变量a的值返回。返回值为:0

    第二次调用【send】函数时,程序从上一次【yield】关键字暂停处开始执行,

    并将send函数传过来的参数赋值给局部变量ret,然后程序继续往下执行

    直到遇到了yield关键字程序暂停,并返回yied关键字后面的值给send。

  6、代码实现

  

def create_num(all_nums):
    a, b = 0, 1
    current_num = 0
    while current_num < all_nums:
        ret = yield a
        print(f"ret的值为:{ret}")
        a, b = b, a+b
        current_num += 1


obj = create_num(10)

# 使用next函数取值
print(next(obj))

# 使用send函数取值并传入数据:“haha”
print(obj.send("haha"))
View Code

运行结果:

0

ret的值为:haha

1

  

示例2:一开始就使用send会报错

def create_num(all_nums):
    a, b = 0, 1
    current_num = 0
    while current_num < all_nums:
        ret = yield a
        print(f"ret的值为:{ret}")
        a, b = b, a+b
        current_num += 1


obj = create_num(10)

# 第一次就使用send函数传值会报错
print(obj.send("haha1"))

print(obj.send("haha2"))
View Code

运行结果:

TypeError: can't send non-None value to a just-started generator

报错原因:这是因为第一次执行生成器是从函数内部的第一行代码开始执行的

  而第一行代码中并未设定一个变量来接收send函数传递过来的数据,所以会报错。

解决方法:

  第一次启动生成器,使用【next】方法

  第一次启动生成器,使用【send】方法,并传递【None】关键字。(一般不使用该方法)

原文地址:https://www.cnblogs.com/yujiemeigui/p/14312699.html