Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python “的含义;OSError:通知位置被next()调用禁用;错误?_Python_Python 3.x_File - Fatal编程技术网

Python “的含义;OSError:通知位置被next()调用禁用;错误?

Python “的含义;OSError:通知位置被next()调用禁用;错误?,python,python-3.x,file,Python,Python 3.x,File,这几乎和我的问题一样。虽然旧问题已经得到了一些有用的解决方法,但错误的含义并不清楚。我想知道是否有人能对此发表评论 我正在学习Python,并大致遵循以下步骤。我在Fedora 23上以交互方式输入了以下内容: $python3 Python 3.4.3(默认,2016年8月9日,15:36:17) linux上的[GCC 5.3.1 20160406(Red Hat 5.3.1-6)] 有关详细信息,请键入“帮助”、“版权”、“信用证”或“许可证”。 >>>打开(“myfile”、“r”)作为

这几乎和我的问题一样。虽然旧问题已经得到了一些有用的解决方法,但错误的含义并不清楚。我想知道是否有人能对此发表评论

我正在学习Python,并大致遵循以下步骤。我在Fedora 23上以交互方式输入了以下内容:

$python3
Python 3.4.3(默认,2016年8月9日,15:36:17)
linux上的[GCC 5.3.1 20160406(Red Hat 5.3.1-6)]
有关详细信息,请键入“帮助”、“版权”、“信用证”或“许可证”。
>>>打开(“myfile”、“r”)作为文件:
...     对于文件中的l:
...         打印(“下一行:\“{}\”。格式(l))
...         打印(“当前位置{:4d}”。格式(file.tell())
myfile
包含几行文本。输出:

下一行:“这是第0行
"
回溯(最近一次呼叫最后一次):
文件“”,第4行,在
OSError:通知位置被next()调用禁用
用谷歌搜索这个错误会得到惊人的6个结果。Windows10上Cygwin上的Python3.6.4也是如此

编辑:

文本文件的
tell()
方法是:

以不透明数字返回当前流位置。号码 通常不表示基础二进制文件中的字节数 储藏室


“不透明数字”似乎表明我不能直接打印它。因此,我将第二个
print()
调用替换为
pos=file.tell()
。相同的结果。

消息的意思与它所说的完全相同:因为您已对该文件调用了
next()
,因此已禁用对该文件使用
tell()

看起来您可能没有调用
next
,但是
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
)上,它们必须做大量工作来支持
tell
;关闭
tell
支持可以让他们跳过该工作。使
next
disable
tell
的原始提交消息是“通过禁用快照更新来加快next()”,这表明这是为了提高效率

对于历史上下文,对
tell
和其他文件方法没有考虑的
next
使用隐藏缓冲区,导致
tell
(和其他文件方法)在对文件的迭代过程中产生不太有意义的结果。当前IO实现将能够在迭代期间支持
tell()
,但
IO.TextIOWrapper
无论如何都会阻止此类调用。
next
和其他方法之间的历史不兼容可能是导致在迭代期间禁用部分文件功能的原因


你没有要求解决办法,但为了那些最终在本页上寻找解决办法的人的利益,我要提到这一点

for line in iter(file.readline, ''):
    ...

将允许您在不禁用
tell
的情况下迭代文本文件的行。(您可以对iter中的行(file.readline,b'')使用
处理二进制文件,但没有太多意义,因为
告诉
禁用机制不适用于二进制文件。)

如果您的文本文件太大,有两种解决方案:

  • 使用
    file.readline()
    而不是
    next()
  • 使用
    offset+=len(line)
    而不是
    file.tell()

  • 在以文本模式打开的文件上,
    tell()
    的“不透明性”意味着,由于行尾转换以及文本文件和二进制文件之间可能存在的任何其他平台特定差异,结果可能与从文件中接收到的字符数不匹配。它唯一的好处就是
    seek()
    稍后返回到相同的位置。但是,该值仍然是一个普通的整数,如果您愿意,没有什么可以阻止您将其打印出来。OP没有显式调用
    next()
    …您的回答的其余部分对我来说听起来更像是纯粹的推测。@martineau:没有显式的
    next
    调用,但是
    for
    隐式调用
    next
    。至于答案的其余部分,主要是推测性的,但是旧的
    next
    /其他方法的不兼容性被记录下来,并且在禁用告知时实现会跳过工作。@martineau:答案现在应该不那么推测性了。这肯定是一个改进,但我认为你至少应该向OP解释他们对文件中的l的
    是如何导致对
    next()
    的隐式调用的,因为这显然不明显,而且他们似乎不理解
    文件和迭代器是如何工作的。@martineau:解释扩展了。
    
    with open(path, mode) as file:
        while True:
            line = file.readline()
            if not line:
                break
            file.tell()
    
    offset = 0
    with open(path, mode) as file:
        for line in file:
            offset += len(line)