当包装(内部)迭代器时,通常必须将public function __construct(\Illuminate\Foundation\Application $app)
{
$app['_foo'] = 'bar';
}
方法重新路由到底层迭代器。请考虑以下示例:
__iter__
变体A和B之间是否有任何显着差异?
Variant A返回一个迭代器对象,该对象已通过class FancyNewClass(collections.Iterable):
def __init__(self):
self._internal_iterable = [1,2,3,4,5]
# ...
# variant A
def __iter__(self):
return iter(self._internal_iterable)
# variant B
def __iter__(self):
yield from self._internal_iterable
从内部迭代中查询。变量B返回一个生成器对象,该对象返回内部可迭代的值。出于某种原因,是其中一种还是其他的?在iter()
中使用collections.abc
版本。 yield from
变体是我到目前为止使用的模式。
答案 0 :(得分:13)
唯一重要的区别是当从迭代中引发异常时会发生什么。使用return iter()
您的FancyNewClass
不会出现在异常回溯中,而yield from
则会出现。虽然可能存在要隐藏包装器的情况,但尽可能在回溯上获得尽可能多的信息通常是件好事。
其他差异:
return iter
必须从全局变量中加载名称iter
- 这可能很慢(虽然不太可能显着影响性能)并且可能会被搞乱(尽管任何覆盖全局变量的人都应该这样做他们得到了什么。)
使用yield from
,您可以在之前和之后插入其他yield
个表达式(尽管您可以同样使用itertools.chain
)。
如上所述,yield from
表单会丢弃任何生成器返回值(即raise StopException(value)
。您可以通过编写return (yield from iterator)
来解决此问题。
这是一个比较两种方法的反汇编并显示异常追溯的测试:http://ideone.com/1YVcSe
使用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 i
RuntimeError
使用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 i
RuntimeError