python - 文件对象迭代器是否“损坏”?
问题描述
根据文档:
一旦迭代器的
__next__()
方法 raiseStopIteration
,它必须在后续调用中继续这样做。不遵守此属性的实现被视为已损坏。
但是,对于文件对象:
>>> 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'
文件对象迭代器是否损坏?这只是那些无法修复的事情之一,因为它会破坏太多依赖它的现有代码吗?
解决方案
我认为这是,如果有的话,那段的文档错误,而不是io
对象中的错误。(并且io
对象并不是唯一的东西——最简单的是,文件的csv.reader
包装器与文件一样可重新启动。)
如果您只是将迭代器用作迭代器,那么一旦它引发,它将继续引发。但是,如果你在迭代器协议之外调用方法,你就不再真正将它用作迭代器,而是将其用作比迭代器更多的东西。在这种情况下,如果有意义的话,将对象“重新填充”似乎是合法的,甚至是惯用的。只要它在作为迭代器嘎嘎作响时从不重新填充自己,只有在它作为其他类型的嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎的时候,它会超出这个范围。
在 C++ 中的类似情况下,语言委员会很可能会声明这会破坏可替代性,因此一旦您在其上调用此类方法,迭代器作为迭代器将变为无效,即使该语言无法强制执行。或者为可再填充的迭代器提出一个全新的协议。(当然 C++ 迭代器与 Python 迭代器并不完全相同,但希望你明白我的意思。)
但在 Python 中,实用性胜过纯粹性。我很确定 Guido 从一开始就打算这样做,并且允许对象这样做并且仍然被视为迭代器,核心开发人员继续打算这样做,只是没有人考虑过如何编写一些东西足够严谨来准确解释它,因为没有人问过。
如果您通过提交文档错误来询问,我敢打赌这一段会得到一个脚注,而不是io
和其他可重新填充的迭代器对象被重新分类为实际上不是迭代器。
推荐阅读
- laravel - 带有 Vue 和 Laravel API 的推送器无法正常工作
- r - 如何从嵌套列表中提取单词对
- python - 为什么“API”请求在 grequests 中返回“无”,而“正常网络抓取”给出 200 响应
- python - Python,Selenium:当ul列表太长时无法通过xpath找到元素
- angularjs - 转到 controllet API 并有一个错误。Asp.Net Core&AngularJS
- c - 在下面的c代码中,为什么第二个元素会自动获取数组第一个元素的值
- rust - 是否可以覆盖在外部 crate 中定义的函数?
- python - 如何制作一个将给定值传递给tkinter中的函数的按钮?
- c++ - 通过 MPI_Recv 接收 char 数组导致输出图像部分为黑色
- php - laravel 视图助手中的 :: (解析范围运算符)是什么?