python - "yield from iterable" vs "return iter(iterable)" -
when wrapping (internal) iterator 1 has reroute __iter__ method underlying iterable. consider following example:
class fancynewclass(collections.iterable): def __init__(self): self._internal_iterable = [1,2,3,4,5] # ... # variant def __iter__(self): return iter(self._internal_iterable) # variant b def __iter__(self): yield self._internal_iterable is there significant difference between variant , b? variant returns iterator object has been queried via iter() internal iterable. variant b returns generator object returns values internal iterable. 1 or other preferable reason? in collections.abc yield from version used. return iter() variant pattern have used until now.
the significant difference happens when exception raised within iterable. using return iter() fancynewclass not appear on exception traceback, whereas yield from will. thing have information on traceback possible, although there situations want hide wrapper.
other differences:
return iterhas load nameiterglobals - potentially slow (although unlikely affect performance) , messed (although overwrites globals deserves get).with
yield fromcan insert otheryieldexpressions before , after (although equally useitertools.chain).as presented,
yield fromform discards generator return value (i.e.raise stopexception(value). can fix writing insteadreturn (yield iterator).
here's test comparing disassembly of 2 approaches , 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_value traceback (most recent call last): file "./prog.py", line 12, in test file "./prog.py", line 10, in runtimeerror using return (yield from):
5 0 load_fast 0 (it) 3 get_iter 4 load_const 0 (none) 7 yield_from 8 return_value traceback (most recent call last): file "./prog.py", line 12, in test file "./prog.py", line 5, in bar file "./prog.py", line 10, in runtimeerror
Comments
Post a Comment