Это мой первый ответ в stackoverflow, поэтому, пожалуйста, потерпите меня. У меня была очень похожая проблема, когда мне нужно было проанализировать несколько журналов, некоторые из которых были огромными, чтобы полностью поместиться в память. Решением этой проблемы является создание конвейера обработки данных, аналогичного конвейеру Unix / Linux. Идея состоит в том, чтобы разбить каждую задачу на отдельные функции и использовать генераторы для достижения более эффективного использования памяти.
import os
import gzip
import re
import fnmatch
def find_files(pattern, path):
"""
Here you can find all the filenames that match a specific pattern
using shell wildcard pattern that way you avoid hardcoding
the file pattern i.e 'messages'
"""
for root, dirs, files in os.walk(path):
for name in fnmatch.filter(files, pattern):
yield os.path.join(root, name)
def file_opener(filenames):
"""
Open a sequence of filenames one at a time
and make sure to close the file once we are done
scanning its content.
"""
for filename in filenames:
if filename.endswith('.gz'):
f = gzip.open(filename, 'rt')
else:
f = open(filename, 'rt')
yield f
f.close()
def chain_generators(iterators):
"""
Chain a sequence of iterators together
"""
for it in iterators:
# Look up yield from if you're unsure what it does
yield from it
def grep(pattern, lines):
"""
Look for a pattern in a line
"""
pat = re.compile(pattern)
for line in lines:
if pat.search(line):
yield line
# A simple way to use these functions together
logs = find_files('messages*', 'One/two/three')
files = file_opener(logs)
lines = chain_generators(files)
each_line = grep('keywords_1', lines)
for match in each_line:
print(match)
Дайте мне знать, если у вас есть какие-либо вопросы относительно моего ответа