我的目标是建立一个日志解析器,它将复制我想要的关键字之间的选定行,并写入一个文件。因为我必须在单个文件中的多个关键字之间进行搜索,所以我想到编写一个函数并在脚本中多次使用它。你知道吗
但是,我无法通过以下脚本实现这一点,并且出现了一个错误:
import re
def myfunc (infile ,outfile, search1 , search2):
fi = infile.readlines()
fo = open(outfile, 'w')
write1 = False
for line in fi:
if re.findall('search1' , str(line)):
write1 = True
elif re.findall('search2', str(line)):
write1 = False
elif write1:
fo.write(line)
fo.close()
fi.close()
return;
text_file = open(input("name of inputfile : "))
resultfile = input("name of outputfile : ")
search1 = "teen"
search2 = "eight"
myfunc (text_file , resultfile , search1 , search2)
我收到以下错误:
Traceback (most recent call last):
File "C:/Users/zoro/PycharmProjects/text-parsing/write selected test 2 sets.py", line 38, in <module>
myfunc (text_file , resultfile , search1 , search2)
File "C:/Users/zoro/PycharmProjects/text-parsing/write selected test 2 sets.py", line 28, in myfunc
fi.close()
AttributeError: 'list' object has no attribute 'close'
这使得
fi
成为文件infile
中的行列表。因此,当您稍后调用fi.close()
时,您试图关闭一个列表,这当然不起作用。你知道吗相反,您需要关闭文件,即
infile
:一般来说,改变变量名是一个好主意,这样就可以清楚地知道它们包含什么。
infile
是一个文件对象,可以从中读取。outfile
是要写入的文件的文件名,因此应该将其命名为outFileName
或其他名称。fi
是infile
中的行列表,因此您应该称之为maybeinFileLines
。你知道吗您还应该避免手动关闭文件对象;而是使用
with
语句来确保它们自动关闭:最后,代码还有另一个问题:
re.findall('search1' , str(line))
这将搜索行中的字符串'search1'
;它将不考虑传递给函数并存储在search1
(和search2
)变量中的值。因此您需要删除那里的引号:re.findall(search1, line)
(您也不需要将行转换为字符串)。你知道吗另外,如果只计算它的真值,那么使用
re.findall()
并不是最好的方法。相反,使用re.search
,它只返回第一个结果(因此对于真正的长行,如果已经找到结果,就不会继续搜索)。如果search1
和search2
不包含实际的正则表达式,而只包含希望在行中找到的字符串,那么还应该使用in
运算符:最后一点注意:文件句柄应该始终从打开它们的同一级别关闭。因此,如果在函数中打开一个文件句柄,那么该函数也应该关闭它。如果在函数外部打开文件,则函数不应将其关闭。打开程序负责关闭文件,对于其他实例,关闭文件可能会导致错误行为,因此您不应该这样做(除非有明确的文档记录,例如函数
doSomethingAndClose
可能会关闭文件)。你知道吗使用
with
语句通常可以避免这种情况,因为您从不手动调用file.close()
,而且with
语句已经确保文件正确关闭。你知道吗如果您想多次使用一个文件,那么您必须seek to the beginning才能再次读取它。在您的例子中,由于您使用
infile.readlines()
将整个文件读入内存,因此最好只从文件中读取一次行,然后将其重新用于多个函数调用:相关问题 更多 >
编程相关推荐