【发布时间】:2018-03-06 10:16:06
【问题描述】:
在 Python3 中迭代文件时如何找出文件光标的位置?
在 Python 2.7 中这很简单,使用 tell()。在 Python3 中,同样的调用会引发 OSError:
Traceback (most recent call last):
File "foo.py", line 113, in check_file
pos = infile.tell()
OSError: telling position disabled by next() call
我的用例是制作一个用于读取大型 CSV 文件的进度条。计算总行数太昂贵并且需要额外的通过。一个近似值很有用,我不关心缓冲区或其他噪声源,我想知道它需要 10 秒还是 10 分钟。
重现问题的简单代码。它在 Python 2.7 上按预期工作,但在 Python 3 上抛出:
file_size = os.stat(path).st_size
with open(path, "r") as infile:
reader = csv.reader(infile)
for row in reader:
pos = infile.tell() # OSError: telling position disabled by next() call
print("At byte {} of {}".format(pos, file_size))
这个答案https://stackoverflow.com/a/29641787/321772 表明问题在于next() 方法在迭代期间禁用了tell()。替代方法是手动逐行读取,但该代码位于 CSV 模块内,因此我无法理解。我也无法理解 Python 3 通过禁用 tell() 会获得什么。
那么在 Python 3 中迭代文件行时找出字节偏移量的首选方法是什么?
【问题讨论】:
-
您可以使用
enumerate并返回行号。这样你就可以给用户一些有用的东西,而不必遍历文件两次 -
@MaartenFabré 当然,打印行号很有用,如果只是为了显示脚本没有卡住,而且如果你不知道长度(即从标准输入)。但是打印“完成 55%,还剩 2 分钟”比“读取 10,543,000 行”要好得多。
标签: python python-3.x csv