2012-07-27 170 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

相關問題