lxsmkv
@lxsmkv
Test automation engineer

Как правильно написать универсальный декоратор который логгирует вызовы методов с входными и выходными параметрами?

У нас самописный интерпретатор питона который "приблизительно" соответствует версии 2.х, и никакие клевые встроенные библиотеки не работают.

Хочу написать декторатор @log при использовании которого логгировался вызваный метод, все его входные параметры и если он возвращает значение то и возвратное значение. Причем если он применяется к методу класса (self) то указывал и название класса из которого его вызвали. Если он применяется к методу который не привязан к классу то без имени класса.

вот что у меня пока есть:
def log(f, *args, **kwargs):
    def func(self,*args,**kwargs):
      result =  f(self,*args, **kwargs)
      print '[DBG] '+str(self.__class__)+'.'+f.__name__+str(args)+str(kwargs) +" --> "+str(result)
      return result
    return func

class MyClass:
  def __init__(self):
    self.name = "Peter"
    self.greeting = "Hello, "
  
  @log
  def get_default_name(self):
    return self.name
  
  @log
  def greet_name(self, name_param):
    print self.greeting + name_param

@log
def standalone_get_name():
  return "Peter Alone"

@log
def standalone_greet_name(name_param):
  print "Greetings, "+name_param


# Test

MyClass().get_default_name()
MyClass().greet_name("Susan")

print standalone_get_name()

standalone_greet_name("Vladislav")


выдача

[DBG] __main__.MyClass.get_default_name(){} --> Peter
Hello, Susan
[DBG] __main__.MyClass.greet_name('Susan',){} --> None
Traceback (most recent call last):
File "python", line 35, in
TypeError: func() takes at least 1 argument (0 given)
  • Вопрос задан
  • 154 просмотра
Пригласить эксперта
Ответы на вопрос 1
@deliro
Агрессивное программирование
1. Разберись получше с декораторами
2. Используй inspect.getcallargs, чтобы лучше понимать, какие конкретно аргументы вкидываются в функцию
3. Используй functools.wraps, чтобы все твои функции продолжали называться так, как они назывались до декорирования
4. print очень неудобная функция для логгирования. Лучше использовать модуль logging и настроить там выдачу в sys.stdout (и в файл, при желании)
5. Разберись с форматированием строк
6. getcallargs также позволит тебе понимать по наличию аргумента "self", метод это или просто функция
7. Выброси наконец второй питон
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы