day5_python之协程函数

一、yield

1:把函数的执行结果封装好__iter__和__next__,即得到一个迭代器
2:与return功能类似,都可以返回值,但不同的是,return只能返回一次值,而yield可以返回多次值
3:函数暂停与再继续运行的状态是有yield保存
def func(count):
    print('start')
    while True:
        yield count
        count += 1
g=func(10)
print(g)
print(next(g))
print(next(g))

二、yield的表达式形式的应用

函数里有yield,一旦执行,那么这个函数就是个生成器
def eater(name):
    print('%s 说:我开动啦' % name)
    while True:
        food = yield
        print('%s eat %s' % (name, food))


alex_g = eater('alex')  ##执行
print(alex_g)###得到生成器<generator object eater at 0x00000000022FB200>

print(next(alex_g))#打印alex 说:我开动啦,返回nane,并且函数暂停在food = yield
print('==============>')
print(next(alex_g))#alex eat None,返回none,然后进入循环,暂定在food = yield
print('==============>')
print(next(alex_g))

三、用法

def eater(name):
    print('%s 说:我开动啦' % name)
    food_list = []
    while True:
        food = yield food_list  # 针对表达式的yield,分两个阶段去使用,第一,初始化,第二,给yield传值
        food_list.append(food)  # ['骨头','菜汤']
        print('%s eat %s' % (name, food))


alex_g = eater('alex')
#####第一阶段:初始化
g = next(alex_g)  # 等同于alex_g.send(None)
print(g)
print('===========>')

# 第二阶段:给yield传值
print(alex_g.send('骨头'))  # 1 先给当前暂停位置的yield传骨头 2 继续往下执行,直到再次碰到yield,然后暂停并且把yield后的返回值当做本次调用的返回值
# print('===========>')
print(alex_g.send('菜汤'))
print(alex_g.send('狗肉包子'))

四、单线程下实现并发的效果

def eater(name):
    print('%s 说:我开动啦' % name)
    food_list = []
    while True:
        food = yield food_list
        food_list.append(food)  # ['骨头','菜汤']
        print('%s eat %s' % (name, food))


def producer():
    alex_g = eater('alex')
    # 第一阶段:初始化
    next(alex_g)#第一阶段
    # 第二阶段:给yield传值
    while True:#第二阶段
        food = input('>>: ').strip()
        if not food: continue
        print(alex_g.send(food))


producer()

五、解决初始化问题

########解决初始化问题
def init(func):
    def wrapper(*args, **kwargs):
        g = func(*args, **kwargs)
        next(g)   ###解决初始化问题
        return g  ##返回的是初始化以后的g

    return wrapper


@init
def eater(name):
    print('%s 说:我开动啦' % name)
    food_list = []
    while True:
        food = yield food_list
        food_list.append(food)  # ['骨头','菜汤']
        print('%s eat %s' % (name, food))


alex_g = eater('alex')
#####第二阶段:给yield传值
print(alex_g.send('骨头'))  # 1 先给当前暂停位置的yield传骨头 2 继续往下执行,直到再次碰到yield,然后暂停并且把yield后的返回值当做本次调用的返回值
print('===========>')

  

  

  

  

原文地址:https://www.cnblogs.com/xiechao621/p/8025306.html