“OSError:告诉下一个()调用禁用位置”的含义“错误?

时间:2018-04-11 23:35:27

标签: python python-3.x file

这与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()来电。结果相同。

1 个答案:

答案 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禁用机制不适用于二进制文件。)