代码之家  ›  专栏  ›  技术社区  ›  juanpa.arrivillaga

文件对象迭代器“坏了吗?”

  •  10
  • juanpa.arrivillaga  · 技术社区  · 8 年前

    根据 documentation :

    一次迭代器 __next__() StopIteration ,它必须 在随后的通话中继续这样做。没有

    但是,对于文件对象:

    >>> f = open('test.txt')
    >>> list(f)
    ['a\n', 'b\n', 'c\n', '\n']
    >>> next(f)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    StopIteration
    >>> f.seek(0)
    0
    >>> next(f)
    'a\n'
    

    文件对象迭代器是否损坏?这仅仅是那些无法修复的事情之一,因为它会破坏太多依赖于它的现有代码吗?

    2 回复  |  直到 8 年前
        1
  •  8
  •   abarnert    8 年前

    我认为这是,如果有的话,那一段的文档错误,而不是 io 物体。(和 对象不是唯一最琐碎的东西 csv.reader

    如果您只是将迭代器用作迭代器,那么一旦它提升,它将继续提升。但是,如果您调用迭代器协议之外的方法,那么实际上您不再将其用作迭代器,而是将其用作迭代器之外的其他东西。在这种情况下,如果对象有意义的话,它看起来是合法的,甚至是惯用的。只要当它作为一个迭代器嘎嘎作响时,它从不重新填充自己,只有当它嘎嘎作响时,它作为其他类型的迭代器超越了它。

    在C++中类似的情况下,语言委员会很可能声明这会破坏可替代性,因此迭代器一旦调用了这样的方法就成为无效的迭代器,即使语言不能强制执行。或者为可重复填充的迭代器提出一个全新的协议。(当然C++迭代器与Python迭代器的内容完全相同,但希望你明白我的意思。)

    但在Python中,实用性胜过纯粹性。我很确定Guido从一开始就打算这样做,并且允许一个对象这样做,并且仍然被认为是一个迭代器,核心开发人员继续打算这样做,只是没有人考虑过如何编写足够严格的东西来准确地解释它,因为没有人问过。

    输入输出

        2
  •  2
  •   wim    7 年前

    是的,根据 stdtypes documentation TextIOWrapper 以及Python 2迭代器 file 都坏了。

    如果您使用的代码假定迭代器严格遵循迭代器协议,那么这是值得记住的。举一个例子,使用Python实现 itertools.dropwhile 与文件迭代器结合是错误的。当另一个进程仍在向日志文件追加行时,通过迭代日志文件可能会遇到问题。

    September 2008 archives 为什么“坏迭代器”坏了?

    Miles :

    严格地说,文件对象是破坏的迭代器。

    Fredrik Lundh :

    Terry Reedy :

    流读取器很可能在一次调用时返回“”,然后在下一次调用时返回非空的内容。读取流的迭代器 并产生任何大小的块,要么阻塞,直到它得到 提高停止迭代直到蒸汽关闭并产生 最后一块数据。

    一家商店关闭到 一件商品在下次交货前缺货的区别 断货并永久停产,或在封闭的道路之间 修理和拆卸。使用相同的符号或

    我认为这种行为在语言上不太可能改变(“实用胜过纯粹”),但也许文档中的语言会软化。如果你想遵循的话,有一个现存的开放性问题: issue23455