Python 协程函数

1.1 协程函数理解

协程函数就是使用了yield表达式形式的生成器

def eater(name):
    print("%s eat food" %name)
    while True:
        food = yield
    print("done")

g = eater("gangdan")
print(g)

结果:
generator object eater at 0x00000000028DC048
这里就证明了g现在就是生成器函数

1. 2 协程函数赋值过程

用的是yield的表达式形式

要先运行next(),让函数初始化并停在yield,相当于初始化函数,然后再send() ,send会给yield传一个值
** next()和send() 都是让函数在上次暂停的位置继续运行,

next是让函数初始化

send在触发下一次代码的执行时,会给yield赋值
**

def eater(name):
    print('%s start to eat food' %name)
    food_list=[]
    while True:
        food=yield food_list
        print('%s get %s ,to start eat' %(name,food))
        food_list.append(food)


e=eater('钢蛋')  # wrapper('')
# print(e)
print(next(e))     # 现在是运行函数,让函数初始化
print(e.send('包子'))  #
print(e.send('韭菜馅包子'))
print(e.send('大蒜包子'))

这里的关键是:
要先运行next()函数

用装饰器函数把next()函数先运行一次:

def start(func):
    def wrapper(*args,**kwargs):
        res=func(*args,**kwargs)  # next()
        next(res)     # 这是关键
        return  res
    return wrapper

@start   # e = start(e)
def eater(name):
    print('%s start to eat food' %name)
    food_list=[]
    while True:
        food=yield food_list
        print('%s get %s ,to start eat' %(name,food))
        food_list.append(food)


e=eater('钢蛋')  # wrapper('钢蛋')  

print(e.send('包子'))
print(e.send('韭菜馅包子'))
print(e.send('大蒜包子'))

在@start # e = start(e) 后面写上,运行start函数,start函数返回wrapper

1.3 协程函数使用装饰器初始化

这里主要是为了防止忘记初始化next操作,在装饰器中添加

def init(func):
    def wrapper(*args,**kwargs):
        res = func(*args,**kwargs)
        next(res)     #  在这里执行next
        return res
    return wrapper

@init            # eater=init(rater)
def eater(name):
    print("%s eat food" %name)
    food_list=[]
    while True:
        food = yield food_list
        print("%s star to eat %s" %(name,food))
        food_list.append(food)
    print("done")

g = eater("gangdan")

# 这里就不需要next
print(g.send("1"))
print(g.send("2"))
print(g.send("3"))
print(g.send("4"))

结果:
gangdan eat food
gangdan star to eat 1
['1']
gangdan star to eat 2
['1', '2']
gangdan star to eat 3
['1', '2', '3']
gangdan star to eat 4
['1', '2', '3', '4']

```
只要用到装饰器函数,马上写装饰器函数,写@init马上想到** eater=init(eater) **,先执行装饰器函数。

关键是next(res),这里是是对生成器进行初始化。这里就会只执行一次,执行完后后面运行的都是e.send()

转载出自:http://www.cnblogs.com/Python666/p/6702422.html

原文地址:https://www.cnblogs.com/liuxiaowei/p/7262276.html