Python: linecache未按预期工作?

3 投票
1 回答
1129 浏览
提问于 2025-04-18 15:59

你好,我有一个Python脚本,想用它来遍历一些文件夹,并从这些文件夹里的文件中提取一些信息。

我有很多个文件夹。每个文件夹里面又有5个子文件夹。在这5个子文件夹里,我有3个文本文件。其中一个是.txt格式的,我不需要管它,另一个是.out格式的,我需要读取它,看看里面是否有一行包含“Fin”这个词。如果有这一行,我就要读取另一个文件,这个文件是.time格式的。这个文件里是Unix系统的时间命令输出,格式大概是这样的:

real    0m1.185s
user    0m0.027s
sys     0m0.026s

我需要从这个文件中提取第二行的内容,也就是“real 0m1.185s”,第一行是一个空行。

所以我会从每个子文件夹里的文件中提取这一行(总共5个文件),然后把每一行表示的秒数加起来,再除以5,得到这5个子文件夹的平均值。

然后,我会为每个平均值写一个输出文件。如果我有两个文件夹:

1/
2/

每个文件夹都有5个子文件夹。

1/1 1/2 1/3 1/4 1/5
2/2 2/2 2/3 2/4 2/5

在这些子文件夹里,我有文本文件,这意味着在1/1这个日期下有一个something.out文件,希望里面有“Fin”这个词。如果有的话,1/1下还有一个something.time文件,我会从中提取出真实时间的那一行。然后我会把1/1、1/2、1/3、1/4和1/5的.time文件中的值加起来,除以5,得到平均值。最后,我把这个平均值写入一个输出文件。

我遇到的问题是,我用命令linecache.getline来提取something.time文件的第二行,但这个方法不太好使,因为它奇怪地在每个子文件夹中提取到的都是同一行。在1/1的子文件夹中,something.time文件的第二行是“real 0m1.809s”。我的代码在这里没问题,但当它进入1/2子文件夹时,提取的第二行却奇怪地显示也是“real 0m1.809s”,但如果我查看1/2的something.time文件,里面显示的是“real 0m1.009s”。

同样的情况也发生在2/这个文件夹里。它在第一个子文件夹中提取到的第一行是正确的,但接下来就重复了那一行5次。

这是我的代码,能不能帮我找出问题出在哪里?

def proArch(dirArch):
    dirList = os.listdir(dirArch)
    resultado = 0
    valores=[]
    for f in dirList:
       if("out" in f):
          for linea in open(f):
            if "Fin" in linea:
              for f_v in dirList:
                if("time" in f_v):
                  linea=linecache.getline(f_v, 2)
                  valores=re.split("['\tms']",linea)[1:3]
                  resultado=(float(valores[0])*60)+float(valores[1])
                else:
                  print("El archivo "+dirArch+" no se proceso bien.")

    return resultado


dirList_g = os.listdir(".")
dirOrig = os.getcwd()
res_tot=0.0
for d in dirList_g:
    if os.path.isdir(d) == True:
     os.chdir(dirOrig+"/"+d)
     dirAct = os.getcwd()
     dirList_w = os.listdir(".")
     for d_w in dirList_w:
       os.chdir(dirAct+"/"+d_w)
       dirArch = os.getcwd()
       res_tot=res_tot+proArch(dirArch)

     res_tot=res_tot/5
     os.chdir(dirOrig)
     with open("output.txt", "w") as text_file:
        text_file.write(dirAct+" "+str(res_tot)+"\n")
     res_tot=0.0

1 个回答

2

可能是因为 linecache 在搞事情,它实际上在缓存上次使用过的一个同名文件的内容。

另外,看起来你没有使用完整的文件路径,这样可能会打开一个和你预期的不一样的文件。

比如,不要用 f_v,你可以试试这样:

filepath = os.path.join(<dirname>, <filename>)

尝试把 linecache.getline 替换成类似下面的东西:

def get_line(filename, n):
    with open(filename, 'r') as f:
        for line_number, line in enumerate(f):
            if line_number == n:
                return line

linecache 不同,这个方法每次都会真正打开文件并读取内容。

最后,如果你用 os.walk 重写这段代码,可能会更清晰、更容易处理:

https://docs.python.org/2/library/os.html

例如:

import os
for root, dirs, files in os.walk('someplace'):
    for dir in dirs:
        # do something with the dirs
    for file in files:
        # do whatever with the files

撰写回答