这个python的yield函数是如何工作的?

2024-09-29 19:18:49 发布

您现在位置:Python中文网/ 问答频道 /正文

def func():
    output = 0
    while True:
        new = yield output
        output = new


genr = func()
print(next(genr))
print(next(genr))
print(next(genr))

输出:

0
None
None

我的想法是:

  1. genr=func()返回生成器,但实际上并不运行它。在
  2. 第一个print(next(genr))从func的开始运行到yield output,但是还没有分配回new,所以输出{}是有意义的。在
  3. 第二个print(next(genr))从将output分配回new开始,下一行output = new将{}和{}都设为0,下一个executeyield output应该返回0,但是为什么它返回None?在

Tags: nonetruenewoutputdefnext意义func
2条回答

yield expression的结果是generator.send()函数发送的值,next(gen)相当于{}。因此,new每次调用next()时都会收到值None。在

如果您改为这样做:

gen = func()
print(next(gen))     # gets the first value of 'output'
print(next(gen))     # send in None, get None back
print(gen.send(10))  # send in 10, get 10 back
print(gen.send(20))  # send in 20, get 20 back

您将得到以下输出:

^{pr2}$

yield语句类似于return返回值,但它不会破坏堆栈帧(函数中知道当前行、局部变量和挂起的try语句的部分)。这样就可以在屈服后恢复函数。在

当您调用一个包含yield的函数时,它返回一个"generator",它允许您运行代码到一个yield,然后从它停止的地方恢复它。在

>>> def squares(n):
        for i in range(n):
            yield i ** 2

>>> g = squares(5)             # create the generator
>>> g
<generator object squares at 0x106beef10>
>>> next(g)                    # run until the first yield
0
>>> next(g)                    # resume after the yield
1
>>> next(g)                    # resume after the yield
4
>>> next(g)                    # resume after the yield
9
>>> next(g)                    # resume after the yield
16
>>> next(g)                    # looping is terminated with a StopIteration
Traceback (most recent call last):
  File "<pyshell#13>", line 1, in <module>
    next(g)                    # looping is terminated with a StopIteration
StopIteration

有趣的是,生成器可以使用send()方法接受值。要为这种发生器启动泵,第一个调用应该是next()。在

^{pr2}$

在您的示例中,您发现next(g)实际上与{}相同。在

以下是the docs要说的:

The value of the yield expression after resuming depends on the method which resumed the execution. If __next__() is used (typically via either a for or the next() builtin) then the result is None. Otherwise, if send() is used, then the result will be the value passed in to that method

下面是一个让所有这些都可见的会话:

>>> def show_expression():
        for i in range(5):
            word = yield 10
            print('The word is %r' % word)

>>> g = show_expression()
>>> next(g)
10
>>> g.send('blue')
The word is 'blue'
10
>>> g.send('no')
The word is 'no'
10
>>> g.send('yellow')
The word is 'yellow'
10
>>> next(g)
The word is None
10
>>> g.send('done')
The word is 'done'
Traceback (most recent call last):
  File "<pyshell#44>", line 1, in <module>
    g.send('done')
StopIteration

希望能解释第一原则中所有的谜团:-)

相关问题 更多 >

    热门问题