Потоковая запись на Python: ротация файлов и освобождение ресурсов
Напишите решение на Python и проверьте его на странице.
Другие упражнения по этой теме: Генераторы Python: задачи на ленивые конвейеры и закрытие ресурсов.
Ротация картриджей самописца
Потоковый самописец непрерывно принимает строки замеров из бесконечного источника событий и сохраняет их в съёмный картридж. Ёмкость каждого такого блока строго ограничена и вмещает записей. В процессе работы регистратор удерживает открытым ровно один накопитель за раз.
Каждые строк, как только квота текущего картриджа заполняется, самописец закрывает его вызовом метода close(), сразу запрашивает у фабрики новый пустой блок и продолжает приём данных. Если же вызывающая программа останавливает опрос генератора досрочно, самописец обязан в блоке finally закрыть активный картридж независимо от того, сколько записей тот успел получить.
Реализуйте генератор пошаговой записи, который вовремя сменяет заполненные блоки и гарантированно закрывает последний открытый накопитель при завершении работы.
Что уже дано
В заготовке объявлена сигнатура функции-генератора rotate_log_records(source, cartridge_factory, capacity) с заглушкой тела. В среде выполнения уже доступны вспомогательный класс накопителя и фабрика проверочных зондов, поэтому реализовывать их заново не требуется.
Что нужно сделать
Реализуйте нативный генератор rotate_log_records(source, cartridge_factory, capacity).
Параметры функции:
source— бесконечный итератор строковых записей;cartridge_factory— вызываемый объект без аргументов, возвращающий новый открытый картридж с методамиwrite(record)иclose();capacity— целое положительное число от 1 до 100, определяющее предельную вместимость одного картриджа.
Правила работы генератора:
- Генератор должен оставаться полностью ленивым: до первого запроса значения (вызова
next()) запрещено запрашивать элементы изsourceили вызыватьcartridge_factory(). - При каждом шаге генератор запрашивает ровно одну очередную запись из
sourceи записывает её в текущий картридж через вызовwrite(record). - Как только в текущий картридж записано ровно
capacityзаписей, генератор закрывает его вызовомclose()и сразу запрашивает новый картридж черезcartridge_factory(). - В процессе записи удерживайте открытым ровно один накопитель. Создание накопителя на замену происходит сразу после закрытия заполненного блока, ещё до того, как генератор отдаст подтверждение текущего шага.
- После завершения шага записи генератор отдает через
yieldисходный объект записанной строки в качестве подтверждения. - Если потребитель досрочно закрывает генератор (вызовом метода
close()), генератор обязан закрыть активный картридж (даже пустой или частично заполненный). Если картридж уже был закрыт, повторный вызовclose()безопасен и идемпотентен.
Количество запросов со стороны вызывающего кода не превышает 1000, а длина каждой строки лежит в диапазоне от 0 до 1000 символов.
Ввод и вывод
Стандартные потоки ввода stdin и вывода stdout в решении не используются: считывать ввод и вызывать print() не нужно. После выполнения кода учащегося проверяющая система считывает из пространства имён модуля функцию верхнего уровня rotate_log_records и вызывает её с проверочными аргументами.
Пример использования
probe = make_log_cartridge_probe(['alpha', 'beta'])
stream = rotate_log_records(probe.source, probe.new_cartridge, 2)
print([next(stream) for _ in range(3)])
stream.close()
print([block.records for block in probe.cartridges])
Вывод:
['alpha', 'beta', 'alpha']
[['alpha', 'beta'], ['alpha']]
Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.
Отправьте решение, чтобы увидеть результаты тестов.
Связанные задачи
- GeneratorExit и yield при close(): вопрос по генераторам Python
- Генераторы Python: синхронизация потоков после фильтрации
- Генераторы Python: разделите поток между двумя потребителями
- Исправьте остановку генераторного конвейера Python
- Генератор скользящего среднего на Python со сбросом окна
- Генераторы Python: закройте второй источник при ошибке первого
