如何在python中获取当前打开的文件行?

Ste*_*ini 7 python file seek line-count

假设您打开一个文件,并在文件中的某处执行seek(),您如何知道当前文件行?

(我亲自解决了一个ad-hoc文件类,它在扫描文件后将搜索位置映射到该行,但我想看到其他提示并将此问题添加到stackoverflow,因为我无法在任何地方找到问题谷歌)

unu*_*tbu 6

当你使用seek()时,python会使用指针偏移来跳转到文件中的所需位置.但是,为了知道当前行号,您必须检查每个字符到该位置.所以你不妨放弃seek()而选择read():

更换

f = open(filename, "r")
f.seek(55)
Run Code Online (Sandbox Code Playgroud)

f = open(filename, "r")
line=f.read(55).count('\n')+1
print(line)
Run Code Online (Sandbox Code Playgroud)

也许您不希望使用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()
Run Code Online (Sandbox Code Playgroud)

这相当于f.seek(num)给你带来的额外好处line_number.


Mar*_*off 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")))))
Run Code Online (Sandbox Code Playgroud)

对于可读性稍差但更懒惰的方法,请使用enumeratedropwhile

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
Run Code Online (Sandbox Code Playgroud)