2012-07-27 4 views
0

로그를 읽고 해석하여 가장 낮은 시작 번호 (머리)를 얻고 인쇄하는 간단한 프로그램을 작성했습니다. 나는이 프로그램을 편집하고 실제 로그 파일을 파싱하기 위해 작성한 클래스와 결합합니다. 본질적으로, 이전 프로그램의 로그에서 간단한 숫자를 기준으로 정렬하는 것과는 대조적으로 이제는 한 클래스의 구문 분석 된 정보를 다른 클래스로 참조해야합니다. 이 작업을 수행하는 가장 편리한 방법이 무엇인지 궁금 해서요. 나는 초보 프로그래머로서 파이썬에서 클래스를 명시 적으로 참조 할 수 있는지 알지 못한다.다른 클래스의 한 클래스 사용

다음은 클래스입니다.

파서

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 기능을 추가하여 내 두 번째 클래스를 편집하기 시작했다. 내가 올바른 길을 가고 있는지 모르겠다.

간단 측면에서, 나는

답변

2

다른 클래스에서 하나 개의 클래스를 사용하는 괜찮 될 "LogLine"로 머리를해야합니다. 로그 파일의 한 행을 구문 분석하고 행을 나타내는 객체를 작성하는 클래스가 하나 있습니다. 로그 파일에서 행을 읽는 다른 클래스가 있습니다. 두 번째 클래스가 첫 번째 클래스를 호출하는 것은 매우 자연스러운 일입니다. 여기

로그 파일의 모든 라인을 읽고 목록 구축 매우 간단한 클래스입니다 :

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()을 호출하면 다음 입력 줄이 표시됩니다. 파일 끝에 도달하면 파이썬은 StopIteration을 발생시켜 파일의 끝을 알립니다.

여기서 코드는 StopIteration 예외를 catch하고 로그 파일 끝에 도달하면 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" 

반복 .__next__() 방법 기능 (파이썬 3.x의)를 호출합니다 파이썬에서 for 루프 그렇지 않으면 .next() 방법 기능 (파이썬 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 (로그) 범위의 I lowest_i = -1 (LEN (로그)) t = 로그 [I] .get_t() == 경우 lowest_i -1 또는 t Raj

+0

네,'logs'가'LogLine' 인스턴스의리스트라면,'logs [i] .get_line()'을 사용하여'. get_line()'메소드 함수는리스트에서'i'의 위치에 저장됩니다. – steveha

+0

감사합니다. 아마도 일관성에 대한 코드를 살펴볼 수 있습니까? 어떤 일이 잘못되면 고칠 필요가 없습니다. 나는 지금 어떻게 구조화하는 법을 배움에 정말로 관심이 있습니다. 붙여 넣기 링크가있는 이메일을 쏠 수 있습니다. 그렇지 않다면, 나는 당신의 시간을 주셔서 감사합니다. – Raj

관련 문제