Регистрация каждого входа / выхода из каждой функции

#python

#python

Вопрос:

В настоящее время я обычно добавляю в свои функции строку журнала с подробными сведениями о переменных, которые вводятся и возвращаются. Однако я ищу элегантный способ обойти это.

Есть ли способ регистрировать каждый ввод в функцию и что возвращается с использованием какой-либо формы магических методов?

Ниже приведен пример,

 class exampleclass(object):
    def __init__(self,size=False):
        self.size = size

    def funt1(self,weight=None):
        return weight

    def funt2(self,shape=None):
        return shape
  

Здесь я хочу зарегистрировать возвращаемую переменную, а также то, что вводится для каждой функции, используя наименьший возможный объем кода.

Комментарии:

1. Самый простой способ, вероятно, использовать pdb для «отладки» вашего кода и отслеживания всех вызовов функций. Если вы не хотите этого делать, то вы, вероятно, захотите использовать метакласс, чтобы избежать украшения каждого метода.

2. @felix001 Мой ответ решил ваш запрос?

3. Это произошло, но мне интересно, есть ли у кого-нибудь другие решения, которые не включали бы декораторов в каждую функцию. Но вместо этого один вызов метода внутри каждого класса.

4. @Bakuriu можете ли вы помочь мне понять, как использовать метаклассы в этом примере?

5. Я думаю, что вызов декораторов — это одна строка.

Ответ №1:

В python есть концепция декораторов. Они помогают вам абстрагироваться от общего кода, который вы хотите внедрить в любую функцию по вашему желанию. Создайте декоратор с именем log следующим образом:

 import logging
from functools import wraps

def log(func):
    @wraps(func)
    def wrapper(self, *args, **kwargs):
            logging.debug("args - %s", str(args))
            logging.debug("kwargs - %s", str(kwargs))
            response = func(self, *args, **kwargs)
            logging.debug("response - %s", str(response))
            return response
    return wrapper
  

Теперь вы можете использовать этот декоратор для любой функции следующим образом:

 @log
def funt1(self,weight=None):
    return weight
  

Приведенный выше код будет регистрировать все аргументы и их возвращаемые значения всего в 1 строке кода.

Вот хороший блог о понимании декораторов.

Комментарии:

1. Было бы лучше использовать logging.debug("args - %s", args) etc