我编写了一个简单的程序来读取日志并解析并获得最低的起始编号(头部)并打印出来。我现在正在编辑该程序并将其与我编写的类组合以解析实际的日志文件。本质上,与基于我之前程序的日志中的简单数字排序相反,我现在需要将解析的信息从一个类引用到另一个类中。我想知道最方便的方法是什么。我是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”
答案 0 :(得分: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),直到{{1引发异常。这里我们定义了两个方法函数名,因此这段代码应该在Python 2.x或Python 3.x中使用。
现在你可以这样做:
StopIteration