最先调用next(my_coro) 这一步通常称为”预激“(prime)协程—即,让协程向前执行到第一个yield表达式,准备好作为活跃的协程使用。
def
simple_coro2
(
a
)
:
print
(
'-> coroutine started: a ='
,
a
)
b
=
yield
a
print
(
'-> Received: b ='
,
b
)
c
=
yield
a
+
b
print
(
'-> Received: c ='
,
c
)
my_coro2
=
simple_coro2
(
14
)
print
(
inspect
.
getgeneratorstate
(
my_coro2
))
# 这里inspect.getgeneratorstate(my_coro2) 得到结果为 GEN_CREATED (协程未启动)
next
(
my_coro2
)
# 向前执行到第一个yield 处 打印 “-> coroutine started: a = 14”
# 并且产生值 14 (yield a 执行 等待为b赋值)
print
(
inspect
.
getgeneratorstate
(
my_coro2
))
# 这里inspect.getgeneratorstate(my_coro2) 得到结果为 GEN_SUSPENDED (协程处于暂停状态)
my_coro2
.
send
(
28
)
# 向前执行到第二个yield 处 打印 “-> Received: b = 28”
# 并且产生值 a + b = 42(yield a + b 执行 得到结果42 等待为c赋值)
print
(
inspect
.
getgeneratorstate
(
my_coro2
))
# 这里inspect.getgeneratorstate(my_coro2) 得到结果为 GEN_SUSPENDED (协程处于暂停状态)
my_coro2
.
send
(
99
)
# 把数字99发送给暂停协程,计算yield 表达式,得到99,然后把那个数赋值给c 打印 “-> Received: c = 99”
# 协程终止,抛出StopIteration
GEN_CREATED
->
coroutine
started
:
a
=
14
GEN_SUSPENDED
->
Received
:
b
=
28
->
Received
:
c
=
99
Traceback
(
most recent call
last
)
:
File
"/Users/gs/coroutine.py"
,
line
37
,
in
<
module
>
my_coro2
.
send
(
99
)
StopIteration
我们已经知道,协程如果不预激,不能使用send() 传入非None 数据。所以,调用my_coro.send(x)之前,一定要调用next(my_coro)。为了简化,我们会使用装饰器预激协程。