Python: linecache未按预期工作?
你好,我有一个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 个回答
可能是因为 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