Рубрики
Без рубрики

Декораторы отладки Python

Иногда при отладке нам нравится печатать/выходить из строя всех входов и выходов метода: Имя, Арг, … Tagged с помощью Python, Debug, Decorator, журнала.

Иногда при отладке нам нравится печатать/выходить из строя всех входов и выходов метода: Имя, 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”