2012-07-27 142 views
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”

回答

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。但我认为这不是解决这个问题的最好方法。让我们把日志文件类工作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" 

一个for环路Python会反复调用.__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 
+0

这是我需要的。感谢您的明确答案。为了跟进,我可以从课堂外调用类方法吗?例如,我写了一个函数来找到最低的t。 'DEF get_line_with_lowest_t(日志): lowest_i = -1 对于i在范围(LEN(日志)): 吨=日志[I] .get_t() 如果lowest_i == -1或叔 Raj 2012-07-27 21:30:36

+0

是的,如果'logs'是'LogLine'实例列表,那么你可以使用'log [i] .get_line()'来调用''。 get_line()'方法函数存储在列表中的位置'i'处。 – steveha 2012-07-27 21:33:53

+0

谢谢。你能否看看我的代码的一致性?如果有什么不对,你不需要修复它。我真的更关心学习如何构建现在。可以用pastebin链接向您发送电子邮件。如果没有,我感谢你的时间。 – Raj 2012-07-27 21:38:15

相关问题