"yield from iterable" vs "return iter(iterable)"
The only significant difference is what happens when an exception is raised from within the iterable. Using return iter()
your FancyNewClass
will not appear on the exception traceback, whereas with yield from
it will. It is generally a good thing to have as much information on the traceback as possible, although there could be situations where you want to hide your wrapper.
Other differences:
return iter
has to load the nameiter
from globals - this is potentially slow (although unlikely to significantly affect performance) and could be messed with (although anyone who overwrites globals like that deserves what they get).With
yield from
you can insert otheryield
expressions before and after (although you could equally useitertools.chain
).As presented, the
yield from
form discards any generator return value (i.e.raise StopException(value)
. You can fix this by writing insteadreturn (yield from iterator)
.
Here's a test comparing the disassembly of the two approaches and also showing exception tracebacks: http://ideone.com/1YVcSe
Using return iter()
:
3 0 LOAD_GLOBAL 0 (iter) 3 LOAD_FAST 0 (it) 6 CALL_FUNCTION 1 (1 positional, 0 keyword pair) 9 RETURN_VALUETraceback (most recent call last): File "./prog.py", line 12, in test File "./prog.py", line 10, in iRuntimeError
Using return (yield from)
:
5 0 LOAD_FAST 0 (it) 3 GET_ITER 4 LOAD_CONST 0 (None) 7 YIELD_FROM 8 RETURN_VALUETraceback (most recent call last): File "./prog.py", line 12, in test File "./prog.py", line 5, in bar File "./prog.py", line 10, in iRuntimeError