yield作为赋值是什么意思?myVar = (yield)

34 投票
3 回答
4948 浏览
提问于 2025-04-15 17:45

我对使用yield来返回一个值有一些了解,主要是通过这个问题学到的。

但是,当yield出现在赋值的右侧时,它到底有什么作用呢?

@coroutine
def protocol(target=None):
   while True:
       c = (yield)

def coroutine(func):
    def start(*args,**kwargs):
        cr = func(*args,**kwargs)
        cr.next()
        return cr 
    return start

我在研究状态机和协程时,发现了这个内容,来自这个博客的代码示例。

3 个回答

0
  • yield 是用来从生成器函数中返回一串数据的,具体返回什么数据是根据你在这个函数里写的逻辑来决定的。
  • send(val) 是一种方法,可以让你从生成器函数外部传入一个你想要的值。

在 Python 3 中,p.next() 不好使,next(p) 在 Python 2 和 3 中都可以用(这是内置的)

在 Python 3 中,p.next() 这个方法不能用了,会报错,但在 Python 2 中是可以正常工作的。

Error: 'generator' object has no attribute 'next'

这里有个演示:

def fun(li):
  if len(li):
    val = yield len(li)
    print(val)
    yield None
    

g = fun([1,2,3,4,5,6])
next(g) # len(li) i.e. 6 is assigned to val
g.send(8) #  8 is assigned to val

12

你可以通过 send 函数向生成器发送值。

如果你执行:

p = protocol()
p.next() # advance to the yield statement, otherwise I can't call send
p.send(5)

那么 yield 会返回 5,这样在生成器内部,c 的值就是 5。

另外,如果你调用 p.next()yield 会返回 None

你可以在 这里 找到更多信息。

40

在一个函数里使用 yield 语句,会把这个函数变成一个“生成器”。简单来说,生成器就是一种可以创建迭代器的函数。通常,我们通过调用 next() 来继续执行这个迭代器。不过,我们也可以用 send() 方法来给这个函数发送值,从而继续执行,而不是用 next()

cr.send(1)

在你的例子中,每次调用时,都会把值 1 赋给 c

实际上, cr.next()cr.send(None) 是等价的,也就是说它们的效果是一样的。

撰写回答