이렇게하는 방법에는 여러 가지가 있습니다. 개인적으로 아마 정규 표현식이 더 효율적이지 않을 것이고 표현식이 복잡하고 융통성이 없기 때문에 정규 표현식 사용을 피할 것입니다. 여기에 내가 생각 해낸 뭔가 :
class Entry:
def __init__(self):
self.time = None
self.animal = None
self.bird = None
self.fish = None
def __repr__(self):
fmt = "{0} {1} {2} {3}".format(
"Time: {time: <{width}}",
"Animal: {animal: <{width}}",
"Bird: {bird: <{width}}",
"Fish: {fish: <{width}}")
return fmt.format(
time=self.time, animal=self.animal,
bird=self.bird, fish=self.fish,
width=12)
def __radd__(self, other):
return self.__add__(other)
def __add__(self, other):
if type(other) == dict:
for i in [self.animal, self.bird, self.fish]:
if i in other: other[i] += 1
else: other[i] = 1
return other
elif type(other) == Entry:
return self.__add__({}) + other
else:
return self.__add__({})
def parse_log(path):
def extract(line):
start = line.find(':') + 1
return line[start:].strip()
entries = []
entry = None
with open(path, 'r') as f:
for line in f.readlines():
if line.startswith('-----'):
if entry: entries.append(entry)
entry = Entry()
elif line.startswith('Time'):
entry.time = extract(line)
elif line.startswith('Animal'):
entry.animal = extract(line)
elif line.startswith('Bird'):
entry.bird = extract(line)
elif line.startswith('Fish'):
entry.fish = extract(line)
if entry: entries.append(entry)
return entries
def print_output_1(entries):
for entry in entries:
print entry
def print_output_2(entries, time):
animals = sum([e for e in entries if e.time == time])
print "Time: {0}".format(time)
print "Name: Count:"
for animal, count in animals.items():
print "{animal: <{width}} {count}".format(
animal=animal, count=count, width=12)
logPath = 'log.log'
time = '2016-07-12 09:15:00'
entries = parse_log(logPath)
print_output_1(entries)
print ""
print_output_2(entries, time)
출력은 (log.log
일치 당신이 준 입력이 주어진) :이 코드가 작동
Time: 2016-07-12 09:00:00 Animal: Brown Bear Bird: White Owl Fish: Salmon
Time: 2016-07-12 09:00:00 Animal: Brown Bear Bird: Parrot Fish: Tuna
Time: 2016-07-12 09:00:00 Animal: Lion Bird: White Owl Fish: Sword Fish
Time: 2016-07-12 09:15:00 Animal: Lion Bird: White Owl Fish: Sword Fish
Time: 2016-07-12 09:15:00
Name: Count:
White Owl 1
Sword Fish 1
Lion 1
방법은 우리의 장점에 객체 지향 프로그래밍을 사용하는 것입니다 로그 항목을 저장하고 특정 형식으로 로그 항목을 표시하며 특정 속성에 따라 로그 항목을 결합해야하는 작업을 단순화하기 위해 우선
은 Entry
객체와 속성 (self.time
, self.animal
, self.bird
, self.fish
)은 로그 엔트리를 나타내고 있습니다. 속성에 저장된 정보가 정확하다고 가정하면 해당 정보를 형식이 지정된 문자열로 나타내는 메서드를 만들 수 있습니다. 메서드 __repr__()
은 파이썬이 객체의 문자열 표현을 원할 때 호출되므로이 코드를 삽입하는 것이 좋습니다. 이 메서드에서는 format
함수를 많이 사용하지만, format
에있는 python 설명서를 탐색 한 후 어떻게 작동하는지 분명해야합니다.
지정한 두 번째 출력을 얻으려면 이러한 입력 개체를 결합하는 방법이 필요합니다. 이것은 여러 가지 방법으로 할 수 있으며 내가 한 방식대로 반드시 최선은 아닙니다. 나는 +
연산자가 객체에서 사용될 때 호출되는 __radd__()
과 __add__()
메쏘드를 사용했다. 이렇게하면 코드 entry1 + entry2
또는 sum([entry1, entry2])
을 사용하여 두 항목의 동물 합계를 얻을 수 있습니다. 그러나 임의의 정보를 포함 할 수 없기 때문에 Entry
클래스는 합계 결과를 저장하는 데 사용할 수 없습니다. 대신 dict
개체를 사용하여 두 개의 Entry
개체를 합산 한 결과로 선택했습니다. 두 개 이상의 개체를 합치려면 Entry
Entry
은 개체와 합계 할 수 있어야합니다. Entry + Entry + Entry
결과는 dict + Entry
이됩니다.
__add__()
함수는 추가 할 개체가 dict
개체인지 확인합니다. 이 경우 항목의 각 동물이 dict
에 이미 있는지 확인합니다. 그렇지 않다면 동물을 열쇠로 추가 할 것입니다. 그렇지 않으면 해당 키의 값이 증가합니다. __radd__()
은 특별한 경우에 사용된다는 점을 제외하고는 __add__()
과 유사합니다. 자세한 내용은 python 설명서를 참조하십시오.
객체가
Entry
인 경우를 들어
이 코드는 각 Entry
개체에서 모든 동물을 수집하고 그 정보에서 dict
을 만들기 위해 작성되었습니다 수 있지만, 코드가 이미 존재하기 때문에 dict
와 함께 Entry
을 추가 하나의 객체를 빈 dict
에 추가 한 다음 결과물 인 dict
을 다른 Entry
객체와 함께 추가하는 것이 더 쉽습니다.
다른 모든 개체의 경우 Entry
은 dict
자체 또는 자체가 빈 dict
으로 추가 된 설명을 반환합니다.
이제는 앞에서 설명한 목표를 달성하기위한 모든 도구가 있습니다. 원하는 출력 1과 일치하는 Entry
의 문자열 표현을 얻으려면 print entry
또는 strrepr = str(entry)
이 필요합니다. 원하는 출력 2를 얻으려면 좀 더 많은 작업이 필요하지만 단순히 동일한 self.time
속성을 가진 모든 항목을 합친 다음 결과 dict를 표시하는 것입니다.
코드의 마지막 부분은 로그를 구문 분석하여 Entry
개체 목록을 만드는 것입니다. 이 코드는 로그를 통해 줄 단위로 걸어서 Entry
정보로 채 웁니다. 나는 이것이 매우 직관적이라고 생각하지만 이해가되지 않는다면 자유롭게 질문 할 수 있습니다.
지금까지 해보신 것은 무엇입니까? 현재 구현할 때 어떤 어려움을 겪고 있습니까? 최신 코드 시도 [mcve]를 제공해 주시겠습니까? – idjaw
어떤 방식 으로든 파일을 읽을 수 있었습니까? – depperm
은 예상 출력을 보여 주거나 데이터 형식에서 미러링해야하는 대상입니까? – patrick