There is a function

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) 

How to wrap it in a decorator so that the function is executed with debugging output (i.e. with print), if necessary, otherwise without it?


After your answers and brief thoughts, it was decided to do this:

 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)) 

How correct is this method? And explain, please, why this method works despite the fact that I wrote func(self, event) , and not startInvRej(self, event) ?



    2 answers 2

    First of all, I recommend switching to Python 3.3. Why not be in trend?

    Further, I can not recommend the built-in logging module

    HOWTO example:

     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') 

    Will output to the specified file:

     DEBUG:root:This message should go to the log file INFO:root:So should this WARNING:root:And this, too 

    Run your application with the key --log=INFO and enjoy filtered logging.

    If the task is to master decorators, you can make it super-stupid:

     # Заглушка, которая не выводит ничего 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( "Не видно" ) 

    I consider this method super stupid, since global variables are evil. In addition, in theory, this method is not safe.

      To be honest, I don’t see the obvious use of the decorator, maybe because I don’t use them so often, but still. Why not try this:

       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) 

      It’s pretty obvious and just looks there :)

      • one
        Thank you for your answer, it is in principle logical, but the fact is that when using a decorator, you would just have to remove the # c # @ decorator sign and the function would be performed with print'ami. I am a beginner python man and I can be mistaken somewhere, of course. And in fact I would like to deal with decorators on an example. - XFixer
      • I understand you, but I can give you a counterexample. And if you want to programmatically influence the output with or without print'ami. But this is me, just as one of the options. To study decorators, the most obvious example is to make a decorator who will count the time that a function is performed. Try it, you can look at the theme of decorators for Habr, there were many strong posts on this topic. - mind_mixer