我正在从David Beazley的精彩演讲中学习协程。Coroutine
我对一个简单的任务示例非常困惑,在该示例中,生成器开始运行而没有继续next()
class Task(object):
taskid = 0
def __init__(self, target):
Task.taskid += 1
self.tid = Task.taskid #Task id
self.target = target #Target coroutine
self.sendval = None #value to send
def run(self):
return self.target.send(self.sendval)
# a very simple generator
def foo():
print('Part 1')
yield
print("Part 2")
yield
它开始时没有next()
In [8]: t1 = Task(foo())
In [9]: t1.run()
Part 1
关于foo
In [10]: f1 = foo()
In [11]: f1.send(1)
TypeError: can't send non-None value to a just-started generator
它应该事先以next()
开始。
我如何理解这种情况?
答案 0 :(得分:1)
错误描述会告诉您什么地方出了问题以及您应该怎么做-您应该将None
发送给刚刚创建的生成器。那是f1.send(None)
而不是f1.send(1)
。通常,协程与装饰器一起使用,就像您在问题中提供的装饰器(类Task
及其方法run
)或以下装饰器一样:
def coroutine(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
generator = func(*args, **kwargs)
next(generator)
return generator
return wrapper