gpt4 book ai didi

python - 基于 yield 的协程是真正的协程吗?

转载 作者:太空宇宙 更新时间:2023-11-03 13:21:41 24 4
gpt4 key购买 nike

我实现 greenlet API 只是为了练习。

from greenlet import greenlet

def test1():
print 12
gr2.switch()
print 34

def test2():
print 56
gr1.switch()
print 78

gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch()

这是我乱七八糟的代码

def test1():
tmp1=yield
print 12
try:
gv2.send(1)
except StopIteration:
pass
tmp1=yield
print 34

def test2():
tmp2=yield
print 56
try:
gv2.send(1)
except StopIteration:
pass
tmp1=yield
print 78

gv1=test1()
gv1.next()
gv2=test2()
gv2.next()

gv1.send(1)

节目,

12
56
Traceback (most recent call last):
File "prog.py", line 26, in <module>
gv1.send(1)
File "prog.py", line 5, in test1
gv2.send(1)
File "prog.py", line 15, in test2
gv2.send(1)
ValueError: generator already executing

所以,我不知道我猜对了,

但是看起来test1发送'1'给test2之后,还是有东西的,

与 gevent 不同,不会发生控制流切换。 test1还有流量。

如果不是,我不明白 greenlet 能做什么,但 python “协程”不存在。

我的问题是

  1. python coroutine(yield-based) 是真正的东西吗(与其他人比较......lisp,ruby,&c)
  2. 如果正确,请提供一些有关该意大利面条代码的提示好吗?

最佳答案

test2() 的生成器实例正在向自身发送一个值。

def test2():
tmp2=yield
print 56
try:
gv2.send(1) # this is the offending line
except StopIteration:
pass
tmp1=yield
print 78

send()恢复生成器,但无论何时在 test2() 中执行代码,它都已经在运行。这就是它呕吐的原因。

您是否要执行:gv1.send(1)?那也行不通。

原因如下:

  • 当前情况:在示例的最后 gv1.send(1) 之前
    • gv1 处于休眠状态
    • gv2 处于休眠状态
  • gv1.send(1) 被调用,这将恢复 gv1
  • gv1 继续 gv2.send(1)
  • 这将恢复 gv2
  • gv2 继续 gv1.send(1)
  • gv1 正在恢复,但是,自上次恢复以来,gv1 尚未达到 yield 语句.因此,它仍在运行,这就是它也会抛出的原因。

本质上,区别可以总结如下:

  • greenlets 共享彼此之间的内在联系:.switch() 暂停当前正在执行的 greenlet 并将恢复。
  • 生成器,另一方面,彼此完全独立。没有执行生成器的共享上下文。
    • yield 将“暂停”生成器
    • next()/send() 将恢复暂停的生成器,在运行的生成器上调用它们将导致异常。

您为什么要访问 gv2(代表 test2 的一个特定实例)?生成器 test2() 应该是独立的,并且不对它的使用方式做出任何假设。如果您决定要从其他范围调用生成器怎么办?无论如何,将值发送给自己没有任何意义:您已经拥有它们。

关于python - 基于 yield 的协程是真正的协程吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11830540/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com