包装(内部)迭代器时,通常必须将__iter__方法重新路由到底层iterable.考虑下面的例子:

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

变体A和B之间有显著差异吗?

推荐答案

唯一显著的区别是,当异常从iterable内部引发时会发生什么.使用return iter()时,FancyNewClass不会出现在异常回溯中,而使用yield from时会出现.一般来说,拥有尽可能多的回溯信息是一件好事,尽管在某些情况下,可能需要隐藏包装器.

其他差异:

  • return iter必须从globals加载名称iter——这可能很慢(虽然不太可能显著影响性能),而且可能会被搞乱(尽管任何像这样覆盖globals的人都应该得到他们应得的).

  • 使用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

Python-3.x相关问答推荐

根据样本量随机 Select 组内样本

如何创建一个polars gramme,给出列表中的列名,

Python gpsd客户端

如何将从维基百科表中抓取的数据转换为字典列表?

为什么 tkinter 在 tkinter 窗口外计算鼠标事件?

如何将函数映射到所有命名元组的元素?

ImportError:抓取数据后找不到 html5lib

有没有一种方法可以通过输入从 0 到 255 的 R、G 和 B 值来生成 RGB colored颜色 ,而无需使用 python 中的 matplotlib 模块?

是否可以将多个 if 转换为数组?

删除括号和大括号中不必要的空格

使用 python-binance 时,heroku [regex._regex_core.error: bad escape \d at position 7] 出错

python 3.7 websockets的1006连接异常关闭错误

使用 python 正则表达式匹配日期

Python - For 循环数百万行

使用 Sympy 方程进行绘图

如何使用 d.items() 更改 for 循环中的所有字典键?

如何替换 Python pathlib.Path 中的子字符串?

命名参数可以与 Python 枚举一起使用吗?

如何为 anaconda python3 安装 gi 模块?

如何将python日志(log)级别名称转换为整数代码