省略文本文件中的标题

时间:2014-10-13 18:05:41

标签: python python-2.7

我有一个文本文件,每次运行脚本时都会收到一行新文件。当一切正常时(在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

这是什么意思,我错过了什么?谢谢!

1 个答案:

答案 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的每个位置并将其全部修复。等等。