Не работает вывод в самописном менеджере контекста

Рейтинг: 0Ответов: 2Опубликовано: 16.01.2023
import time 

class TimeManager: 
    def __init__(self):
        self.startTime = time.time()
        self.timeExec = 0
    
    def __enter__(self): 
        self.timeEnd = time.time()
        self.timeExec = self.timeEnd - self.startTime
        return self.timeExec
    
    def __exit__(self, exception_type, exception_val, trace):
        return True
    
    def printTime(self): 
        print(self.timeExec)

def foo():
    a = 1
    for i in range(10000):
        a += i 
    print(a)
    return a


with TimeManager() as tm: 
    # foo()
    print('freg')
    tm.printTime()

При выводе на принт хотелось бы, чтобы выводил разницу во времени или хотя бы что-нибудь. Но вывод как будто вообще не работает. Консоль просто пустая. При этом обычный принт срабатывает

Ответы

▲ 5Принят

Замечания:

  • Из __enter__ лучше возвращать self
  • Разницу лучше считать в __exit__ и там можно выводить
  • Намудрили с определением разницы по времени - ее нужно брать в конце и от того же метода, от которого берете начальное время, т.е. time.time()
  • Имена переменных и методов рекомендуется в змеиной нотации писать

Обратите внимание, что __exit__ вызывается после выхода из контекстного менеджера, а значит вывод tm.print_time() будет раньше, чем аналогичный в __exit__ и разница по времени на этот момент еще не будет известна

Пример:

import time


class TimeManager:
    def __init__(self):
        self.start_time = 0
        self.time_exec = 0

    def __enter__(self):
        self.start_time = time.time()
        return self

    def __exit__(self, exc_type, exc_value, exc_traceback):
        self.time_exec = time.time() - self.start_time
        self.print_time()

    def print_time(self):
        print(f'Total time: {self.time_exec:.3f} sec')


def foo():
    a = 1
    for i in range(10000):
        a += i
    print(a)
    return a


with TimeManager() as tm:
    # foo()
    print('freg')
    tm.print_time()

▲ 4

Чтоб получить менеджер через as нужно вернуть self, а не значение.

def __enter__(self):
    .....
    return self

Вы бы увидели ошибку если б не заглушили все ошибки в

def __exit__(self, exception_type, exception_val, trace):
    return True  # глушит ошибки