В enter сохраните time.perf_counter() и верните self; в exit запишите разницу в elapsed. Возврат False не подавит исключение внутри with.
Таймер, реализованный как контекстный менеджер
В __enter__ сохраните time.perf_counter() и верните self; в __exit__ запишите разницу в elapsed. Возврат False не подавит исключение внутри with.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Необходимо создать класс Timer, который работает в роли контекстного менеджера. При входе в конструкцию with начинается измерение времени, а при выходе из блока вычисленное время сохраняется в атрибут elapsed.
with Timer() as t:
time.sleep(1)
print(t.elapsed)
Ответ
В enter сохраните time.perf_counter() и верните self; в exit запишите разницу в elapsed. Возврат False не подавит исключение внутри with.
Реализация измеряет длительность в секундах:
import time
class Timer:
def __enter__(self):
self.started = time.perf_counter()
self.elapsed = None
return self
def __exit__(self, exc_type, exc_value, traceback):
self.elapsed = time.perf_counter() - self.started
return False
elapsed устанавливается даже при исключении из блока. Значение после sleep(1) будет около одной секунды, но не обязательно ровно 1. perf_counter подходит для измерения интервалов, в отличие от календарных часов. Один экземпляр не предназначен для вложенных одновременных измерений.