我有一个文本文件,每次运行脚本时都会收到一行新文件。当一切正常时(在try块中),它会收到一个新行,当出现错误时(从except块),它会收到一个新行。在添加新行方面,一切正常。但我也有1个标题,这是第一次创建/写入文本文件时添加的。因此,每次运行脚本时,它不仅会添加其中一个新行,而且还会添加标题。我可以注释掉我添加标题的行,然后删除循环,但这是如何正常工作的?我无法弄清楚它是如何与for循环一起工作的(我想我可能需要其中一个......对python来说很新)。
所以我尝试了:
log = 'log.txt'
logfile = file(log, "a") # 'a' for appending the existing file
然后我得到了我的大标题信息(格式完全相同):
header ='''
############################################################
# #
# #
# Log file for bla station #
# #
# xxxxxxxxxxxxxxxxxxxxxxxxx #
# xxxxxxxxxxxxxxxxxxxxxxx #
# #
# Contact: bla@bla.at #
# #
############################################################\n\n'''
然后在except块(例如)中进一步:
error = "ERROR! No file found!"
for head in open(logfile, 'r'):
if head == header:
continue
logfile.write(header)
logfile.write(timestamp + error + '\n')
但是我收到以下错误消息:
for head in open(logfile, "r"):
TypeError: coercing to Unicode: need string or buffer, file found
这是什么意思,我错过了什么?谢谢!
答案 0 :(得分:2)
你的直接问题是这一行:
for head in open(logfile, 'r'):
open
函数想要一个文件名,但你给它一个开放的file
对象,如下所示:
logfile = file(log, "a") # 'a' for appending the existing file
这就是TypeError
告诉你的。它试图将file
对象用作指定文件名的字符串或缓冲区,而file
对象不知道如何执行此操作。
你想要的是open(log, 'r')
。
作为旁注,你真的应该在写作时使用with
语句(或以其他方式关闭文件),尤其是。
但这里还有另一个问题。您的header
多行,但每个head
都是一行,因此head == header
无法成为真正的行。
更重要的是,这里的逻辑似乎没有意义。 尝试要做的代码是:对于除标题之外的文件中的每个现有行,添加新标题和新日志消息。所以,如果您的文件看起来像这样:
HEADER
message 1
message 2
message 3
你最终会得到:
HEADER
message 1
message 2
message 3
HEADER
new message
HEADER
new message
HEADER
new message
这不可能是你想要的。我认为你只是试着写一个标题,如果它没有标题,然后以任何一种方式编写新的日志行,对吧?所以,你的逻辑必须实际说出来。
一个非常简单的解决方案是假设任何非空文件都有标题。你可以这样做,例如:
with open(log, 'r+') as logfile:
logfile.seek(0, os.SEEK_END)
if not logfile.tell():
# The end is still position 0, so we have to write a header
logfile.write(header)
logfile.write(timestamp + error + '\n')
最后,您应该考虑查看logging
模块。这是相当大而复杂的,但请注意,文档从三个教程开始,可能会得到你想要的。您可以非常轻松地编写一个处理程序子类,只有在创建新文件时才会写入标头。这样做的一个优点是,您可以稍后将其扩展到例如使用旋转日志文件,并且您现有的逻辑将继续工作(您只需要混合使用不同的基本处理程序)。或者您可以通过指定不同的格式化程序来更改日志格式,而不必查找显式使用timestamp + msg
的每个位置并将其全部修复。等等。