拆卸发电机会产生令人惊讶的结果
Disassembling a generator yields surprising results
我知道如何使用生成器,但我对它们的内部结构一无所知。我试过这个:
In [4]: def f(): yield 1
In [6]: type(f())
Out[6]: generator
现在拆解一下:
In [7]: dis.dis(f)
1 0 LOAD_CONST 1 (1)
3 YIELD_VALUE
4 POP_TOP
5 LOAD_CONST 0 (None)
8 RETURN_VALUE
为什么操作码建议 return None
而 f
实际上是 returns 生成器?
所有函数 return None
如果没有明确的 return,则生成器也不例外。从 Python 3.3 开始,生成器在结束时可以 return a final value,但在 Python 2.7 中,如果您使用 return
提前结束函数,则必须使用空格 return。
这是 'limitation' 如何实现 Python 帧;您必须有一个 RETURN_VALUE
操作码才能干净地退出框架并展开堆栈,并且该操作码始终需要一个操作数。
调用该函数仍会生成一个生成器,但 字节代码 不会执行,直到您实际调用生成器上的 .next()
方法。
我知道如何使用生成器,但我对它们的内部结构一无所知。我试过这个:
In [4]: def f(): yield 1
In [6]: type(f())
Out[6]: generator
现在拆解一下:
In [7]: dis.dis(f)
1 0 LOAD_CONST 1 (1)
3 YIELD_VALUE
4 POP_TOP
5 LOAD_CONST 0 (None)
8 RETURN_VALUE
为什么操作码建议 return None
而 f
实际上是 returns 生成器?
所有函数 return None
如果没有明确的 return,则生成器也不例外。从 Python 3.3 开始,生成器在结束时可以 return a final value,但在 Python 2.7 中,如果您使用 return
提前结束函数,则必须使用空格 return。
这是 'limitation' 如何实现 Python 帧;您必须有一个 RETURN_VALUE
操作码才能干净地退出框架并展开堆栈,并且该操作码始终需要一个操作数。
调用该函数仍会生成一个生成器,但 字节代码 不会执行,直到您实际调用生成器上的 .next()
方法。