I know how to use generators but I don't know anything about their internals. I tried this:
In [4]: def f(): yield 1
In [6]: type(f())
Out[6]: generator
Now I disassemble it:
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
Why does the opcodes suggest return None
while f
actually returns a generator?
All functions return None
at their end if there is no explicit return, generators are no exception. As of Python 3.3, generators can return a final value when ending, but in Python 2.7 a blank return is mandatory if you use return
to end the function early.
This is a 'limitation' of how Python frames are implemented; you have to have a RETURN_VALUE
opcode to exit the frame cleanly and unwind the stack, and that opcode requires an operand, always.
Calling the function still produces a generator, but the byte code isn't executed until you actually call the .next()
method on the generator.