yield ->协程

160 阅读2分钟

对yield的理解

在函数当中使用了yield,则该函数就称为一个生成器 yield理解 1、当成return 程序返回 2、当成生成器

def foo():
    print("starting...")
    while True:
        """
        使用到yield说明该函数就不是一个普通的函数,
        而是一个生成器
        """
        res = yield 4
        print("res:", res)


# g就为一个生成器对象
g = foo()
print(next(g))
print("*"*20)
print(next(g))

yield from

使用yield from 中可以使用可迭代对象,也就是说在迭代器中使用迭代对象 下面是普通使用yield的语法

# 字符串
astr = 'ABC'
# 列表
alist = [1, 2, 3]
# 字典
adict = {"name": "wangbm", "age": 18}
# 生成器
agen = (i for i in range(4, 8))


def gen(*args, **kw):
    for item in args:
        for i in item:
            yield i


new_list = gen(astr, alist, adict, agen)
print(list(new_list))
# ['A', 'B', 'C', 1, 2, 3, 'name', 'age', 4, 5, 6, 7]

下面使用yield from ,和yield对比,明显少了一个for循环,因为yield from后面直接接收可迭代对象即可

# 字符串
astr = 'ABC'
# 列表
alist = [1, 2, 3]
# 字典
adict = {"name": "wangbm", "age": 18}
# 生成器
agen = (i for i in range(4, 8))


def gen(*args, **kw):
    for item in args:
        yield from item


new_list = gen(astr, alist, adict, agen)
print(list(new_list))
# ['A', 'B', 'C', 1, 2, 3, 'name', 'age', 4, 5, 6, 7]

yield 实现协程

import time


def A():
    while True:
        print("-----------A---------")
        yield
        time.sleep(0.5)


def B(c):
    while True:
        print("------B-------")
        c.__next__()
        time.sleep(0.5)


a = A()
B(a)

使用send传输数据

其中send会将数据发送给res,res接收后便往下执行输出结果,最后再一轮循环直到遇到yield

def foo():
    print("staring")
    while True:
        res = yield 4
        print("res:", res)


g = foo()
print(next(g))
print(g.send(10))

yield结合send实现生产者和消费者传递数据

def produce(c):
    """
    在一个生成器函数未启动之前,是不能传递数值进去。
    必须先传递一个None进去或者调用一次next(g)方法,才能进行传值操作 
    """
    c.send(None)
    for i in range(1, 10):
        print(i)
        print("生产者生产产品%d" %i)
        c.send(str(i))


def consumer():
    while True:
        res = yield
        print("消费者消费产品:", res)


c = consumer()
produce(c)