1

For debugging purpose I want to write a function to do this:

  1. If debug_mode == 0 doesn't echo any message.
  2. If debug_mode == 1 echoes the message to the stdout with print()
  3. If debug_mode == 2 echoes the message to a log file

I've thinked do that with function decorators (that I've never used before).

Actually, I want to substitute some print() that I've put in some points to show me intermediate values and while learn about function decorators.

I don't want to create a class to do that. This is my approach, but it doesn't work:

import logging

FORMAT = '%(asctime)s %(levelname)s %(message)s %(funcName)s'
logging.basicConfig(filename='example.log', level=logging.DEBUG, format=FORMAT, datefmt='%m/%d/%Y %I:%M:%S %p')

def debug(func):
    def _debug(deb=0, *args, **kwargs):
        if deb == 1:
            print(msg)
            func(*args, **kwargs)
        if deb == 2:
            logging.debug(msg)
    return _debug

@debug
def echo(msg, deb=0):
    pass

if __name__ == "__main__":
    debug_mode = 1
    echo("This is a debugging message!", debug_mode)

It will be better if I haven't to pass the param debug_mode and in the decorator function I can use the debug state directly from the __main__.

Trimax
  • 2,413
  • 7
  • 35
  • 59
  • Why not making the debug settings global? – bereal Sep 03 '14 at 09:22
  • @bereal That is my planned solution if I don't find any other. I ever try to avoid the use of globals. – Trimax Sep 03 '14 at 10:01
  • Same here, but if there is a place for globals in the world, then it's debugging & logging. You can also rely on an environment variable, then `debug` may even return the original function if debugging is unneeded. – bereal Sep 03 '14 at 10:04
  • Why not use logging module? Printing debugging information is troublesome, any trivial thing like 'when to flush' may affect time difference between print() call and effect appearing. – Łukasz Rogalski Dec 01 '14 at 17:03

1 Answers1

1

The problem with your code is the way you pass arguments. When you do echo("This is a debugging message!", debug_mode) you are in fact invoking def _debug(deb=0, *args, **kwargs) and all the arguments are messed up (deb becomes "This is a debugging message!" etc). On StackOverflow there is an amazing tutorial on how to use decorators.

I'm not sure why do you need *args, **kwargs in you code. I personally believe that there is no need for any decoration in your particular case. Anyway, for educational purposes the working code with decorators may loo like:

import logging

FORMAT = '%(asctime)s %(levelname)s %(message)s %(funcName)s'
logging.basicConfig(filename='example.log', level=logging.DEBUG, format=FORMAT, datefmt='%m/%d/%Y %I:%M:%S %p')

def debug(func):
    def _debug(msg, deb=0):
        if deb == 1:
            func(msg, deb)
        if deb == 2:
            print 'Log: ' + msg + ' Level: ' + str(deb)
            logging.debug(msg)
    return _debug

@debug
def echo(msg, deb):
    print 'Echo: ' + msg + ' Level: ' + str(deb) 

if __name__ == "__main__":
    echo("This is a debugging message!")
    echo("This is a debugging message!", 0)
    echo("This is a debugging message!", 1)
    echo("This is a debugging message!", 2)

And the output:

Echo: This is a debugging message! Level: 1
Log: This is a debugging message! Level: 2
Community
  • 1
  • 1
Konstantin
  • 2,937
  • 10
  • 41
  • 58