0

我编写了一个简单的程序来读取日志并解析并获取最低的起始编号(头部)并打印它。我现在正在编辑该程序并将其与我编写的用于解析实际日志文件的类相结合。本质上,与基于我之前程序的日志中的简单数字进行排序相反,我现在需要将解析后的信息从一个类引用到另一个类。我想知道最方便的方法是什么。我是 python 的初学者程序员,不知道我是否可以显式引用该类。

这是课程。

解析器

class LogLine:

    SEVERITIES = ['EMERG','ALERT','CRIT','ERR','WARNING','NOTICE','INFO','DEBUG']
    severity = 1


    def __init__(self, line):
        try:
            m = re.match(r"^(\d{4}-\d{2}-\d{2}\s*\d{2}:\d{2}:\d{2}),?(\d{3}),?(\s+\[(?:[^\]]+)\])+\s+[A-Z]+\s+(\s?[a-zA-Z0-9\.])+\s?(\((?:\s?\w)+\))\s?(\s?.)+", line)
            timestr, msstr, sevstr, self.filename, linestr, self.message = m.groups()
            self.line = int(linestr)
            self.sev = self.SEVERITIES.index(sevstr)
            self.time = float(calendar.timegm(time.strptime(timestr, "%Y-%m-%d %H:%M:%S,%f"))) + float(msstr)/1000.0
            dt = datetime.strptime(t, "%Y-%m-%d %H:%M:%S,%f")
        except Exception:
            print 'error',self.filename


    def get_time(self):
        return self.time
    def get_severity(self):
        return self.sev
    def get_message(self):
        return self.message
    def get_filename(self):
        return self.filename
    def get_line(self):
        return self.line

分拣机

class LogFile:

    def __init__(self,filepath):
        self.logfile = open(filepath, "r")
        self.head = None

    def __str__(self):
        return "x=" + str(self.x) + "y="+str(self.y)

    def readline(self):
        if self.head != None:
            h = self.head
            self.head = None
            return h
        else:
            return self.logfile.readline().rstrip(' ')

    def get_line(self):
        if self.head == None:
            self.head = self.readline().rstrip(' ')
            return self.head.get.line()
        else:
            return self.head.get.line()

    def close (self):
        self.logfile.close()

我已经开始通过添加 get_line 函数来编辑我的第二堂课。不知道我是否走在正确的轨道上。

简单来说,我需要头部变成“LogLine”

4

1 回答 1

2

使用另一个班级的一个班级是可以的。您有一个类可以解析日志文件中的一行并构建一个表示该行的对象;你有另一个类从日志文件中读取行。二等舱叫一等舱是很自然的事。

这是一个非常简单的类,它从日志文件中读取所有行并构建一个列表:

class LogFile(object):
    def __init__(self,filepath):
        with open(filepath, "r") as f:
            self.lst = [LogLine(line) for line in f]

您可以看到它self.lst被设置为输入日志文件中的行列表,而不仅仅是行的文本;该代码正在调用LogLine(line)以存储LogLine. 如果需要,您可以在构建列表后对其进行排序:

self.lst.sort(key=LogLine.get_line)

如果日志文件非常大,则构建列表可能不切实际。你有一个.get_line()方法函数,我们可以使用它:

class LogFile(object):
    def __init__(self,filepath):
        self.logfile = open(filepath, "r")

    def get_line(self):
        try:
            line = next(self.logfile)  # get next line from open file object
            return LogLine(line)
        except StopIteration:  # next() raises this when you reach the end of the file
            return None  # return 

    def close(self):
        self.logfile.close()

open()可以迭代打开的文件对象(由函数返回)。我们可以调用next()这个对象,它会给我们下一个输入行。当到达文件末尾时,Python 将引发StopIteration文件末尾的信号。

此处代码将捕获StopIteration异常并None在到达日志文件末尾时返回。但我认为这不是处理这个问题的最佳方式。让我们让 LogFile 类在for循环中工作,例如:

class LogFile(object):
    def __init__(self,filepath):
        self.f = open(filepath)

    def __next__(self):  # Python 3.x needs this to be named "__next__"
        try:
            line = next(self.f)
            return LogLine(line)
        except StopIteration:
            # when we reach the end of input, close the file object
            self.f.close()
            # re-raise the exception
            raise
    next = __next__  # Python 2.x needs this to be named "next"

Python 中的for循环将重复调用.__next__()方法函数 (Python 3.x) 或.next()方法函数 (Python 2.x),直到StopIteration引发异常。在这里,我们定义了两个方法函数名称,所以这段代码应该可以在 Python 2.x 或 Python 3.x 中工作。

现在你可以这样做:

for ll in LogFile("some_log_file"):
    ... # do something with ll, which will always be a LogLine instance
于 2012-07-27T19:37:28.547 回答