#python #python_32 #декоратор
Есть функция 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)?
Ответы
Ответ 1
Прежде всего, рекомендую перейти на 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( "Не видно" ) Считаю этот метод супер-тупым, так как глобальные переменные - зло. Кроме того, теоретически, этот метод непотокобезопасен.Ответ 2
Если честно, тут очевидного применения декоратора я не вижу, может потому что не так часто ими пользуюсь, но всё же. А почему бы не попробовать вот так: def startInvRej(self, event, debug=False): if 2 < event.button < 4: self.canvCoor = [] self.frameCoor = [] if debug: print(event.x) print(event.xdata) self.frameCoor.append(event.x) self.canvCoor.append(float(event.xdata)) if debug: print(self.frameCoor) print(self.canvCoor) Там ведь достаточно очевидно и просто всё выглядит :)
Комментариев нет:
Отправить комментарий