python协程函数

协程函数

从语法上来看,协程和生成器类似,都是定义体中包含yield关键字的函数。
yield在协程中的用法:

  • 在协程中yield通常出现在表达式的右边,例如:datum = yield,可以产出值,也可以不产出–如果yield关键字后面没有表达式,那么生成器产出None.
  • 协程可能从调用方接受数据,调用方是通过send(datum)的方式把数据提供给协程使用,而不是next(…)函数,通常调用方会把值推送给协程。
  • 协程可以把控制器让给中心调度程序,从而激活其他的协程

所以总体上在协程中把yield看做是控制流程的方式

实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def menu(x):
print("welcome %s to shaxian restaurant" % x)
men_list = []
while True:
print(men_list)
food = yield men_list
print("%s start to eat %s" % (x, food))
men_list.append(food)


g = menu('张三')
next(g)
g.send('包子') # 将'包子'传给yield ,然后赋值给了food,然后从上次暂停的位置接着执行代码,直到又到下一个yield
g.send('饺子')
g.send('牛肉面')

g.send与next(g)的区别是:

1.如果函数内yield是表达式形式,那么必须先next(g)

2.二者的共同之处都是可以让函数在上一次暂停的位置继续运行,不一样的地方在于send在触发下一次代码的执行时,会顺便给yield传一个值

如果不想写next的初始化,而直接调用send,可以选择加个装饰器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def happy(fuc):
def f1(*args, **kwargs):
res = fuc(*args, **kwargs)
next(res) #让函数调用时自动初始化next
return res
return f1


@happy
def menu(x):
print("welcome %s to shaxian restaurant" % x)
men_list = []
while True:
print(men_list)
food = yield men_list
print("%s start to eat %s" % (x, food))
men_list.append(food)


g = menu('张三')

g.send('包子')
# 将'包子'传给yield ,然后赋值给了food,然后从上次暂停的位置接着执行代码,直到又到下一个yield
g.send('饺子')
g.send('牛肉面')