Как мне узнать, в каком блоке кода вызывается моя функция в python

#python #python-3.x #contextmanager

Вопрос:

У меня есть следующий класс

 class Time:
    def __init__(self) -> None:
        self.time  = 0;
    def __enter__(self):
        self.start = time()
        return self
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.end  = time()
        self.time = self.end - self.start
        print(f'The execution of the block took {self.time}s')
 

и я называю это так

 with Time():
    # block 1
    for i in range(100000):
        for ii in range(100):
            pass
    with Time():
        # block 2
        for i in range(1000):
            prime(i)
        with Time():
            # block 3
            ''
 

Это результат, который я получаю:

 The execution of the block took 1.6689300537109375e-06s
The execution of the block took 0.0006444454193115234s
The execution of the block took 0.4997687339782715s
 

который находится в блоке заказов 3, 2, 1.

Но что, если бы у меня была программа побольше, как бы я проверил, какой блок вызывает мою функцию?

Я пытался это сделать:

 print(f'The execution of the block {locals()} took {self.time}s')
 

Но это просто дает мне местных жителей класса.

Ответ №1:

Вы можете использовать строковый аргумент с меткой.

Код:

 class Time:
    def __init__(self, label="") -> None:
        self.time = 0
        self.label = label

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

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.end = time()
        self.time = self.end - self.start
        if not self.label:
            print(f'The execution of the block took {self.time}s')
        else:
            print(f'The execution of the block {self.label} took {self.time}s')
 

Если вы хотите, чтобы имена блоков были от 1 до количества блоков, вы можете использовать переменную класса, одну из замечательных функций Python.

Код:

 class Time:
    index = 0

    def __init__(self) -> None:
        self.time = 0
        self.index = Time.index
        Time.index  = 1

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

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.end = time()
        self.time = self.end - self.start
        print(f'The execution of the block {self.index} took {self.time}s')