Python file.tell() 给出奇怪的数字? [英] Python file.tell() giving strange numbers?

查看:47
本文介绍了Python file.tell() 给出奇怪的数字?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 Windows 64 位上使用 Python 3.3.0.

I am using Python 3.3.0, on windows 64bit.

我有一个如下所示的文本文件:(请参阅底部的 mediafire 下载链接)

I have a text file as shown below: (see bottom for download link at mediafire)

hello

-data1:blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah


-data2:blah blah blah blah blah blah blah blah blah blah blah
-data3: Empty

-data4: Empty

我正在尝试浏览文件,因此我使用 .tell() 来确定我的位置.但是,当阅读如下所示的文件行时,我得到了一个非常奇怪的结果:

I'm trying to navigate around the file, and thus I use .tell() to figure out what my position is. However, when reading through the lines of the file as shown below, I get a very strange result:

f=open("test.txt")
while True:
    a = f.readline()
    print("{}    {}".format(repr(a),f.tell()))
    if a == "":
        break

结果:

'hello\n'    7
'\n'    9
'-data1:blah blah blah blah blah blah blah blah blah blah blah blah blah blah bl
ah blah\n'    18446744073709551714
'\n'    99
'\n'    101
'-data2:blah blah blah blah blah blah blah blah blah blah blah\n'    164
'-data3: Empty\n'    179
'\n'    181
'-data4: Empty'    194
''    194

第三行的 18446744073709551714 是怎么回事?尽管它看起来像是一个不可能的值,但 f.seek(18446744073709551714) 是一个可以接受的值,它显然让我看到了第三行的结尾.不过,我似乎无法弄清楚原因.

What's with the 18446744073709551714 for the 3rd line? Though it looks like an impossible value, f.seek(18446744073709551714) is an acceptable value that apparently does bring me to the end of the 3rd line. Though, I can't seem to figure out why.

在二进制模式下打开 tell() 没有问题:

Opening in binary mode gives no problems with tell():

f=open("test.txt","rb")
while True:
    a = f.readline()
    print("{}    {}".format(repr(a),f.tell()))
    if a == b"":
        break

结果:

b'hello\r\n'    7
b'\r\n'    9
b'-data1:blah blah blah blah blah blah blah blah blah blah blah blah blah blah b
lah blah\r\n'    97
b'\r\n'    99
b'\r\n'    101
b'-data2:blah blah blah blah blah blah blah blah blah blah blah\r\n'    164
b'-data3: Empty\r\n'    179
b'\r\n'    181
b'-data4: Empty'    194
b''    194

test.txt 文本文件可在此处下载,只有 194 字节:http://www.mediafire.com/?1wm4lujb2j48y23

The test.txt text file is downloadable here, just a tiny 194 bytes: http://www.mediafire.com/?1wm4lujb2j48y23

推荐答案

这是由 UNIX 样式的行结尾引起的记录行为:

It's a documented behaviour caused by UNIX-style line endings:

file.tell()

返回文件的当前位置,如stdioftell().

Return the file’s current position, like stdio's ftell().

注意:在 Windows 上,tell() 可以在读取 Unix 风格的文件时返回非法值(在 fgets() 之后)行尾.使用二进制模式('rb') 来规避这个问题.

Note: On Windows, tell() can return illegal values (after an fgets()) when reading files with Unix-style line-endings. Use binary mode ('rb') to circumvent this problem.

<小时>

以上文档摘自python2.7.4文档.python3 的文档略有变化,因为现在有一个处理 I/O 的类层次结构,而我找不到这些信息.您的测试表明行为无论如何都没有改变.此外,python3.3 的源代码在 tell 调用的函数之前有一个 XXX Windows 支持可能不完整 注释.


The above documentation is taken from the python2.7.4 documentation. The documentation for python3 changed a bit, since there is now a hierarchy of classes that handle I/O and I can't find this bit of information. Your test shows that the behaviour didn't change anyway. Also the source code for python3.3 has an XXX Windows support below is likely incomplete comment before the function called by tell.

python 错误跟踪器中有一个 issue 与此相关,Catalin Iacob 的最终评论是:

There is an issue in python bug tracker related to this, and the final comment by Catalin Iacob is:

我试图重现这个,在我的磁盘上选择了一个文件,确实我得到了一个负数,但该文件具有 Unix 行结尾.这是记录在 http://docs.python.org/2/library/stdtypes.html#file.tell所以可能没什么可做的.

I tried to reproduce this, picked a file on my disk and indeed I got a negative number, but that file has Unix line endings. This is documented at http://docs.python.org/2/library/stdtypes.html#file.tell so probably there's nothing to do then.

至于阿明在 msg180145 中的报告,虽然不直观,这与 ftell 在 Windows 上的行为相匹配,如备注中所述部分http://msdn.microsoft.com/en-us/library/0ys3hc0b%28v=vs.100%29.aspx.文件对象上的 tell() 方法被明确记录为匹配ftell 行为:返回文件的当前位置,如 stdio 的ftell()".所以即使它根本不直观,也可能是最好保持原样.tell() 返回直观的非零在 Python3 和 Python 2.7 上使用 'a' 打开时的位置io.open 所以它在未来无论如何都是固定的.

As for Armin's report in msg180145, even though it's not intuitive, this matches ftell's behavior on Windows, as documented in the Remarks section of http://msdn.microsoft.com/en-us/library/0ys3hc0b%28v=vs.100%29.aspx. The tell() method on fileobjects is explicitly documented as matching ftell behavior: "Return the file’s current position, like stdio‘s ftell()". So even though it's not intuitive at all, it's probably better to leave it as is. tell() returns the intuitive non zero position when opening with 'a' on Python3 and on Python 2.7 when using io.open so it's fixed for the future anyway.

所以这似乎是一个不会修复"的错误.可能有人应该打开一个问题(评论该问题),因为在 python3 文档中根本没有提到这个事实.

So it seems like a "wontfix" bug. Someone should probably open an issue(commented the issue) because this fact is not mentioned at all in python3 documentation.

根据 Antoine Pitrou python3 不使用 ftell() 完全不同,因此这似乎是一个不同的错误.此外,该错误在 python3.2.3 中不可重现,并且可能是在修复此问题时引入的(至少,它是我能在 3.2.3 和 3.3 之间找到 tell() 实现的唯一变化)

According to Antoine Pitrou python3 doesn't use ftell() at all, hence this seems to be a different bug. Also the bug is not reproducible in python3.2.3 and was probably introduced when fixing this issue (at least, it's the only change I can find to the implementation of tell() between 3.2.3 and 3.3)

最后根据 io 模块文档 tell 方法返回自文件开始以来的字节数.返回值是一个不透明数字",这意味着您可以使用它的唯一方法是将其传递给 seek 以返回该位置.其他操作没有意义.事实上,在 python3.2.3 之前,返回的值只是一个实现细节.

Last edit: According to the io module documentation the tell method does not return the number of bytes since the beginning of a file. The returned value is an "opaque number", which means that the only way you can use it is to pass it to seek to get back at that position. Other operations aren't meaningful. The fact that until python3.2.3 the value returned was what you'd expect was only an implementation detail.

注意this中的信息文档的部分只是错误,希望将来会得到修复.

Note that the information in this section of the documentation is simply wrong and, hopefully, it will be fixed in the future.

这篇关于Python file.tell() 给出奇怪的数字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆