这与How to solve "OSError: telling position disabled by next() call"几乎相同。虽然较旧的问题已经收到了一些有用的解决方法的答案,但错误的含义并不清楚。我想知道是否有人可以对此发表评论。
我正在学习Python并且松散地关注tutorial。我在Fedora 23上以交互方式进入了以下内容:
$ python3
Python 3.4.3 (default, Aug 9 2016, 15:36:17)
[GCC 5.3.1 20160406 (Red Hat 5.3.1-6)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> with open("myfile","r") as file:
... for l in file:
... print("Next line: \"{}\"".format(l))
... print("Current position {:4d}".format(file.tell()))
myfile
包含几行文字。输出:
Next line: "This is line number 0
"
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
OSError: telling position disabled by next() call
Google搜索此错误会产生高达6的结果。在Windows 10上的Cygwin上使用Python 3.6.4也是如此。
修改
文本文件的tell()
方法为documented as follows:
将当前流位置作为不透明数字返回。数字 通常不表示底层二进制文件中的多个字节 存储
“不透明数字”似乎表明我不能只打印它。所以,我用print()
替换了第二个pos = file.tell()
来电。结果相同。
答案 0 :(得分:10)
该消息的含义正是它所说的:因为您在文件上调用了next()
,因此该文件上tell()
的使用已被禁用。
您可能看起来不像next
,但for
循环会隐式调用它。一个for
循环:
for element in thing:
do_stuff_with(element)
是
的语法糖iterator = iter(thing) # the real implementation doesn't use a variable
while True:
try:
element = next(iterator) # here's the next() call
except StopIteration:
break
do_stuff_with(element)
对于文件,iter(file)
返回文件,循环调用文件next
。
至于为什么调用next
禁用tell()
,这是为了提高效率。它仅适用于文本文件(特别是io.TextIOWrapper
),它必须执行bunch extra工作以支持tell
;关闭tell
支持可以让他们跳过这项工作。 next
使tell
禁用next
的{{3}}的原始提交消息为&#34;然后通过禁用快照更新来加速next()。&#34;,指示它&#39;为提高效率。
对于历史背景,change使用tell
的隐藏缓冲区tell
和其他文件方法未考虑,导致tell()
(和其他文件)方法)在迭代文件期间产生非常有意义的结果。当前的IO实现将能够在迭代期间支持io.TextIOWrapper
,但next
无论如何都会阻止此类调用。 for line in iter(file.readline, ''):
...
与其他方法之间的历史不兼容可能导致在迭代期间禁用部分文件功能被认为是合理的。
您没有要求解决方法,但为了让最终在此页面上寻找解决方法的人们的利益,我会提到
tell
将允许您迭代文件的行而不禁用for line in iter(file.readline, b'')
。 (您可以将tell
用于二进制文件,但没有多大意义,因为mio
禁用机制不适用于二进制文件。)