Класс-декоратор Python: сохранение каждого N-го результата
Напишите решение на Python и проверьте его на странице.
Другие упражнения по этой теме: Классы-декораторы Python: задачи на call, методы и состояние.
Периодический снимок результатов
Модуль профилирования следит за работой вычислительной модели и периодически сохраняет снимки возвращаемых ею значений для последующего аудита. Чтобы не переполнять журнал, класс-декоратор прореживает поток результатов с заданным шагом : он пропускает вызовы через целевую функцию, но заносит значение в локальный список снимков только при каждом -м успешном расчёте, начиная с самого первого — то есть на 1-м, -м и так далее. Если очередной вызов завершается исключением, этот запуск не идёт в счёт успешных, снимок не создаётся, а сама ошибка пробрасывается дальше без задержки.
В любой момент оператор может вмешаться в регулярный цикл с помощью метода take_snapshot(). Этот вызов переводит дозатор в режим ожидания внеочередной фиксации: декоратор обязательно сохраняет результат ровно следующего успешного расчёта, независимо от того, на каком месте в интервале тот оказался. Как только внеочередной снимок сделан, штатный шаг отсчёта запускается заново уже от этой зафиксированной точки.
Реализуйте класс-декоратор, который накапливает выборку успешных результатов с заданным шагом и синхронизирует интервал сохранения при ручном запросе оператора.
Что уже дано
В заготовке кода представлен класс SnapshotSampler с методами __init__, __call__ и take_snapshot. Вспомогательная функция observe_scheduled_snapshots доступна во время проверки и служит для тестирования работы экземпляров.
Что нужно сделать
Реализуйте класс SnapshotSampler(function, step):
- Конструктор принимает два аргумента:
function— обычную синхронную вызываемую функцию;step— целое положительное число шага интервала от1до100.- Экземпляр хранит общедоступный атрибут
snapshots— список, в который в порядке получения добавляются зафиксированные результаты. - Метод
__call__(*args, **kwargs)передаёт аргументы в целевую функцию без изменений и возвращает её реальный результат: - если вызов целевой функции завершается исключением (производным от
BaseException), это исключение пробрасывается без изменений, счёт успешных вызовов не изменяется, а вsnapshotsничего не добавляется; - фиксируются результаты успешных вызовов: 1-й, затем -й и далее с тем же шагом;
- в проверочных сценариях результаты представляют собой неизменяемые типы (
int,bool,str,None,tuple); создавать их глубокие копии не требуется. - Метод
take_snapshot(): - не вызывает целевую функцию и возвращает
None; - регистрирует запрос на обязательное сохранение результата ровно следующего успешного вызова целевой функции;
- запрос на внеочередной снимок сохраняется при возникновении ошибок в последующих вызовах, пока не произойдёт успешный расчёт;
- после фиксации этого результата отсчёт регулярного интервала сбрасывается и возобновляется заново от этой точки (следующий регулярный снимок произойдёт через
stepуспешных вызовов); - если внеочередной запрос совпадает с очередным регулярным сохранением, результат записывается в
snapshotsровно один раз. - Независимые экземпляры класса не влияют на состояние друг друга (поддерживается чередование от 1 до 3 экземпляров, до 1000 вызовов на каждый).
Ввод и вывод
Стандартные потоки ввода stdin и вывода stdout в решении не используются: считывать ввод и вызывать print() не нужно. После выполнения кода учащегося проверяющая система считывает из пространства имён модуля класс верхнего уровня SnapshotSampler и вызывает его методы.
Пример использования
sampler = SnapshotSampler(lambda value: value * 10, 3)
for value in (1, 2, 3, 4):
sampler(value)
print(sampler.snapshots)
sampler.take_snapshot()
sampler(5)
print(sampler.snapshots)
Вывод:
[10, 40]
[10, 40, 50]
Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.
Отправьте решение, чтобы увидеть результаты тестов.
Связанные задачи
- Класс-декоратор Python: когда вызывается init
- Класс-декоратор метода Python: почему теряется self
- Класс-декоратор Python: ограничение изменения результата между вызовами
- Класс-декоратор Python: баланс доступных вызовов функции
- Класс-декоратор Python: изменение аргумента первых N вызовов
- Класс-декоратор Python: буфер событий и пакетная запись
