Skip to main content
 首页 » 编程设计

生成器中的 python3 send() 函数

2025年05月04日16qq78292959

根据 docs , 发送() 函数:

"Resumes the execution and “sends” a value into the generator function. The value argument becomes the result of the current yield expression. The send() method returns the next value yielded by the generator, or raises StopIteration if the generator exits without yielding another value. When send() is called to start the generator, it must be called with None as the argument, because there is no yield expression that could receive the value."

但我不明白,为什么“值参数成为当前 yield 表达式的结果”在下面的例子中没有发生:

def gen(): 
    yield 1 
    x = (yield 42) 
    print(x) 
    yield 2 
 
>>>c=gen() #create generator 
>>>next(c) #prints '1' and stop execution, which is caused by yield 1 
>>>c.send(100) #prints '42', because 'The send() method returns the next value yielded by the generator' 
>>>next(c) #prints 'None' and '2' 

那么,尽管我通过 c.send(100) 向它发送 100,为什么 x 变量保持“无”? 看起来,右侧的 yield 表达式分两步工作:首先它返回生成器调用者的值,第二个返回生成器内部发送函数的参数。如果在 send(42) 之前添加额外的 next(c),我将获得预期的行为并且程序会打印“100”。从文档中我不清楚为什么这两个步骤在我调用 send() 时不应该同时发生。

请您参考如下方法:

So why x variable stays 'None' dispite i send 100 to it by c.send(100)?

因为当前的yield不是你想的那个,而是之前那个。

当您发送 100 时,生成器仍停止在 yield 1,而不是 yield 42,因此 100 将是 yield 1< 的结果,不是 yield 42。

为了看得更清楚,如果您修改生成器以在 z 变量中检索 yield 1 的内容,您将看到 z 确实包含 100:

>>> def gen(): 
...     z = yield 1 
...     x = (yield 42) 
...     print(x, z) 
...     yield 2 
...  
>>> c=gen() 
>>> next(c) 
1 
>>> c.send(100) 
42 
>>> next(c) 
None 100 
2 
>>> 

这就是额外的 next() 将打印 100 的原因。回到你的代码:

def gen(): 
    yield 1  # first next(), stops here (before "getting out" of yield) 
    x = (yield 42) # second next(), stops here (before "getting out" of yield), 
                   # so, when you send(100), then 100 is given to x and execution goes on, so: 
    print(x)  # 100 is printed 
    yield 2  # ... and 2.