打开多个文件中的特定行

opening specific lines inside multiple files

我正在尝试打开多个文件的特定行和 return 每个文件的行。我的解决方案非常耗时。你有什么建议吗?
func.filename: 给定文件的名称
func.start_line: 给定文件中的起点
func.endline: 给定文件中的终点

def method_open(func):
    try:
        body = open(func.filename).readlines()[func.start_line:
                                               func.end_line]
    except IOError:
        body = []
        stderr.write("\nCouldn't open the referenced method inside {0}".
                     format(func.filename))
        stderr.flush()
    return body

请记住,有时打开的文件 func.filename 可能相同,但不幸的是,大多数情况下情况并非如此。

readlines 的问题是它将整个文件读入内存,而 linecache 也是如此。

您可以一次读一行并在读到 func.endline

时立即中断循环,这样可以节省一些时间

但我发现最好的方法是使用 itertools.islice

这里是我对一个约 9701k 行的 130MB 文件所做的一些测试的结果:

--- 1.43700003624 seconds --- f_readlines
--- 1.00099992752 seconds --- f_enumerate
--- 1.1400001049 seconds --- f_linecache
--- 0.0 seconds --- f_itertools_islice

在这里你可以找到我使用的脚本

import time
import linecache
import itertools


def f_readlines(filename, start_line, endline):
    with open(filename) as f:
        f.readlines()[5000:10000]


def f_enumerate(filename, start_line, endline):
    result = []
    with open(filename) as f:
        for i, line in enumerate(f):
            if i in range(start_line, endline):
                result.append(line)
            if i > endline:
                break


def f_linecache(filename, start_line, endline):
    result = []
    for n in range(start_line, endline):
        result.append(linecache.getline(filename, n))


def f_itertools_islice(filename, start_line, endline):
    result = []
    with open(filename) as f:
        resultt = itertools.islice(f, start_line, endline)
        for i in resultt:
            result.append(i)


def runtest(func_to_test):
    filename = "testlongfile.txt"
    start_line = 5000
    endline = 10000
    start_time = time.time()
    func_to_test(filename, start_line, endline)
    print("--- %s seconds --- %s" % ((time.time() - start_time),func_to_test.__name__))

runtest(f_readlines)
runtest(f_enumerate)
runtest(f_linecache)
runtest(f_itertools_islice)