如何在Python中获取当前打开文件的行号?
假设你打开了一个文件,然后在文件的某个位置使用了 seek(),那么你怎么知道现在是文件的哪一行呢?
我个人是通过一个临时的文件类来解决这个问题的,这个类会在扫描文件后把当前位置和行数对应起来。不过我想看看其他人的建议,所以把这个问题放到stackoverflow上,因为我在谷歌上找不到相关的信息。
2 个回答
6
当你使用seek()的时候,Python会用指针偏移量来跳到文件中的某个位置。但是,要知道当前的行号,你得一个一个字符地检查,直到那个位置。所以其实你可以放弃使用seek(),改用read():
把
f = open(filename, "r")
f.seek(55)
换成
f = open(filename, "r")
line=f.read(55).count('\n')+1
print(line)
也许你不想用f.read(num),因为如果num很大,这可能会占用很多内存。在这种情况下,你可以使用像这样的生成器:
import itertools
import operator
line_number=reduce(operator.add,( f.read(1)=='\n' for _ in itertools.repeat(None,num)))
pos=f.tell()
这相当于f.seek(num)
,而且还可以让你得到line_number
。
4
这是我解决这个问题的方法,尽量做到懒惰:
from random import randint
from itertools import takewhile, islice
file = "/etc/passwd"
f = open(file, "r")
f.seek(randint(10,250))
pos = f.tell()
print "pos=%d" % pos
def countbytes(iterable):
bytes = 0
for item in iterable:
bytes += len(item)
yield bytes
print 1+len(list(takewhile(lambda x: x <= pos, countbytes(open(file, "r")))))
如果你想要一种稍微不那么容易读但更懒惰的方法,可以使用 enumerate
和 dropwhile
:
from random import randint
from itertools import islice, dropwhile
file = "/etc/passwd"
f = open(file, "r")
f.seek(randint(10,250))
pos = f.tell()
print "pos=%d" % pos
def countbytes(iterable):
bytes = 0
for item in iterable:
bytes += len(item)
yield bytes
print list(
islice(
dropwhile(lambda x: x[1] <= pos, enumerate(countbytes(open(file, "r"))))
, 1))[0][0]+1