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 iter
has load nameiter
globals - potentially slow (although unlikely affect performance) , messed (although overwrites globals deserves get).with
yield from
can insert otheryield
expressions before , after (although equally useitertools.chain
).as presented,
yield from
form 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