Страницы

Поиск по вопросам

воскресенье, 14 апреля 2019 г.

Как обернуть функцию декоратором?

Есть функция
def startInvRej(self, event): if 2 < event.button < 4: self.canvCoor = [] self.frameCoor = [] print(event.x) print(event.xdata) self.frameCoor.append(event.x) self.canvCoor.append(float(event.xdata)) print(self.frameCoor) print(self.canvCoor)
Как завернуть ее в декоратор, чтобы функция выполнялась с отладочным выводом (т.е. с print'ами), если это необходимо, а иначе без него?

После Ваших ответов и недолгих раздумий было решено сделать таким образом:
def decorator(func): def wrapped(self, event): print(event.x) print(event.xdata) func(self, event) print(self.frameCoor) print(self.canvCoor) return wrapped
@decorator def startInvRej(self, event): if event.button ==3: self.canvCoor = [] self.frameCoor = [] self.frameCoor.append(event.x) self.canvCoor.append(float(event.xdata))
Насколько этот способ корректен? И объясните, пожалуйста, почему такой способ работает несмотря на то, что я написал func(self, event), а не startInvRej(self, event)?


Ответ

Прежде всего, рекомендую перейти на Python 3.3. Зачем быть не в тренде? Далее, не могу не порекомендовать встроенный модуль logging Пример из HOWTO import logging logging.basicConfig(filename='example.log',level=logging.DEBUG) logging.debug('This message should go to the log file') logging.info('So should this') logging.warning('And this, too') Выведет в указанный файл: DEBUG:root:This message should go to the log file INFO:root:So should this WARNING:root:And this, too Запускаете своё приложение с ключом --log=INFO и наслажлаетесь фильтрованным логированием. Если задача именно в освоении декораторов, можно сделать супер-тупо: # Заглушка, которая не выводит ничего def log_print_stub( *args, **kwargs ): pass
# глобальная переменная, с помощью которой # вызывается либо функция print для логгирования, # либо log_print_stub, чтобы ничего не делать log_print = log_print_stub
# декоратор, изменяющий состояние глобальной переменной # перед вызовом декорируемой функции def logged(fn): def wrapped(*args, **kwargs): global log_print log_print = print result = fn(*args, **kwargs) log_print = log_print_stub return result return wrapped
# пример:
@logged def show_log( message ): print( "show_log" ) log_print( message, " ", message )
def dont_show_log( message ): print( "dont_show_log") log_print( message, " ", message )
# декорированная функция выведет "Видно Видно" show_log( "Видно" ) # не декорированная ничего дополнительно не делает dont_show_log( "Не видно" ) Считаю этот метод супер-тупым, так как глобальные переменные - зло. Кроме того, теоретически, этот метод непотокобезопасен.

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

Отправить комментарий