我想知道在 Python 3 中编写协程的最佳实践是什么。我正在开发基本方法,这些方法应该接受一些输入(使用 .send() 方法),对此输入执行计算,然后产生输出。
我发现的第一种方法基本上是执行以下操作:
def coroutine(func):
data = yield
while 1:
data = yield func(data)
这似乎可行,但循环中的线路让我心烦意乱。它似乎首先产生一个函数,并且then接受输入并执行任务after恢复。这对我来说完全不直观。
我正在考虑的另一种方法是:
def coroutine():
while 1:
data = yield
[ do stuff with data here ... ]
yield result
这段代码对我来说更容易理解,而且它还允许我将代码直接放入生成器中,而不是传递函数。但用起来很烦人。对生成器的每个实际调用(例如“gen.send(2)”)都必须后跟“gen.send(None)”,以将生成器推进到下一个收益。
在我看来,这里的问题源于“yield”关键字被用于两个不同的事物:返回语句和输入语句。
如果可能的话,我想要一种方法,让我接受输入,对该输入进行计算,然后产生输出,而不必像第一种方法那样传递函数并使用单行,或者像第二种方法那样发送无关的值方法。我怎样才能做到这一点?
请注意:实际上,我将发送多个值。因此,存在无关的“g.send(None)”语句的问题变得更糟。
您可以按照第一个示例中的方式进行操作。你只需要在循环内“用数据做一些事情”。这是一个例子:
def coroutine():
data = yield
while True:
print("I am doing stuff with data now")
data = data * 2
data = yield data
你可以这样使用它:
>>> co = coroutine()
>>> next(co)
>>> co.send(1)
I am doing stuff with data now
2
>>> co.send(88)
I am doing stuff with data now
176
你是对的yield
扮演双重角色,既产生结果又接受随后通过 via 传入的值send
。 (同样地,send
发挥双重和互补的作用,因为每个send
调用返回生成器产生的值。)请注意那里的顺序:当你有一个yield
表达,它first产生值 out,然后是值yield
表达式变成任何东西sent
in 然后.
这可能看起来是“向后”的,但是您可以通过循环执行它来使其“向前”,就像您基本上已经做的那样。这个想法是你首先产生一些初始值(可能是无意义的)。这是必要的,因为你不能使用send
在产生一个值之前(因为不会有yield
表达式来评估发送的值)。然后,每次你使用yield
,您给出“当前”值,同时接受用于计算“下一个”值的输入。
正如我在评论中提到的,从您的示例中并不清楚您为什么要使用生成器。在许多情况下,您只需编写一个具有自己的传入和传出方法的类即可实现类似的效果,并且如果您编写该类,则可以使 API 成为您想要的任何内容。如果您选择使用生成器,则必须接受以下双重输入/输出角色:send
and yield
。如果您不喜欢这样,请不要使用生成器(或者,如果您需要它们提供的挂起函数状态,您可以使用它们,但用一个将发送与生成分开的类包装它们)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)