Иногда при отладке нам нравится печатать/выходить из строя всех входов и выходов метода: Имя, Args, Kwargs, Dict
и т.п.
У нас было бы немного ide отладка
Особенности для этой цели, но иногда нам нужна ручная отладка.
И хотя ручная отладка я не хочу писать logger.debug (
каждой из двух строк модуля.
Решение: Питоны декораторы
Сначала настроить регистратор
Анкет Для получения подробной информации перейдите в наш пост Конфигурация ведения журнала Python Анкет Затем создайте модуль для нашего декораторы отладчика
#!/usr/bin/env python3 # -*- coding: utf-8 -*- # utils/debuggers.py class Debugger(object): """ Debug a method and return it back""" enabled = False def __init__(self, func): self.func = func def __call__(self, *args, **kwargs): if self.enabled: logger.debug(f'Entering : {self.func.__name__}') logger.debug(f'args, kwargs : {args, kwargs}') logger.debug(f'{self.func.__name__} returned : {self.func(*args, **kwargs)}') return self.func(*args, **kwargs)
Затем назовите его и украсьте свой метод, как ниже:
#!/usr/bin/env python3 # -*- coding: utf-8 -*- # main.py from utils.debuggers import Debugger @Debugger def my_func(a, b, c, d): return a + b + c + d if __name__ == "__main__": Debugger.enabled = True args_dict = dict( a=1, b=2, c=5, d=-10 ) my_func(**args_dict)
Вывод будет похож на:
2019-07-21 18:43:25,635 [DEBUG] __main__: Entering : my_func 2019-07-21 18:43:25,635 [DEBUG] __main__: args, kwargs: ((), {'a': 1, 'b': 2, 'c': 5, 'd': -10}) 2019-07-21 18:43:25,635 [DEBUG] __main__: my_func returned -2
Если вы хотите функцию вместо класса для отладки:
#!/usr/bin/env python3 # -*- coding: utf-8 -*- # utils/decorators.py import functools def debugmethod(func): """ Debug a method and return it back""" @functools.wraps(func) def wrapper(*args, **kwargs): return_value = func(*args, **kwargs) logger.debug(f'Calling : {func.__name__}') logger.debug(f'args, kwargs: {args, kwargs}') logger.debug(f'{func.__name__} returned {return_value}') return return_value return wrapper
Также, если вам нравится знать время выполнения метода;
#!/usr/bin/env python3 # -*- coding: utf-8 -*- # utils/decorators.py import time def timerun(func): """ Calculate the execution time of a method and return it back""" @functools.wraps(func) def wrapper(*args, **kwargs): start = time.time() result = func(*args, **kwargs) duration = time.time() - start logger.debug(f"Duration of {func.__name__} function was {duration}.") return result return wrapper
Выход:
2019-07-21 18:43:25,636 [DEBUG] __main__: Duration of my_func was 0.00023937225341796875.
Вы можете объединить свои декораторы, как ниже:
#!/usr/bin/env python3 # -*- coding: utf-8 -*- # main.py from utils.debuggers import debugmethod, timerun @timerun @debugmethod def my_func(a, b, c, d): return a + b + c + d if __name__ == "__main__": Debugger.enabled = True args_dict = dict( a=1, b=2, c=5, d=-10 ) my_func(**args_dict)
Вывод должен быть таким:
2019-07-21 18:43:25,635 [DEBUG] __main__: Calling : my_func 2019-07-21 18:43:25,635 [DEBUG] __main__: args, kwargs: ((), {'a': 1, 'b': 2, 'c': 5, 'd': -10}) 2019-07-21 18:43:25,635 [DEBUG] __main__: my_func returned -2 2019-07-21 18:43:25,636 [DEBUG] __main__: Duration of my_func was 0.00023937225341796875.
ОК, все сделано.
Оригинал: “https://dev.to/serhatteker/python-debug-decorators-56jj”