Printing to STDOUT and the log file when deleting ANSI color codes

I have the following functions for coloring my screen messages:

def error(string): return '\033[31;1m' + string + '\033[0m' def standout(string): return '\033[34;1m' + string + '\033[0m' 

I use them as follows:

 print error('There was a problem with the program') print "This is normal " + standout("and this stands out") 

I want to write the output to a file (in addition to STDOUT) WITHOUT ANSI color codes, I hope, without the need to add a second line of "registration" in each print statement.

The reason is that if you just python program.py > out , then the out file will have ANSI color codes that look awful if you open it in a text editor.

Any tips?

+7
python logging stdout
source share
3 answers

The sys.stdout.isatty function can help:

 from sys import stdout def error(string, is_tty=stdout.isatty()): return ('\033[31;1m' + string + '\033[0m') if is_tty else string def standout(string, is_tty=stdout.isatty()): return ('\033[34;1m' + string + '\033[0m') if is_tty else string 

This is actually one of the few uses that I can think of to use a default argument that is not set to None , because the default arguments are evaluated at compile time in Python, and not at run time, as in C ++ ...

Also, the behavior can be explicitly overridden if you really need to, although this does not allow you to control stdout itself when redirecting it. Is there a reason why you are not using the logging module (perhaps you did not know about this)?

+9
source share

If you want to print to both the terminal and the log file, I would suggest using a logging module. You can even define a custom formatter, so writing to a file can clear terminal codes:

 import optparse import logging def error(string): return '\033[31;1m' + string + '\033[0m' def standout(string): return '\033[34;1m' + string + '\033[0m' def plain(string): return string.replace('\033[34;1m','').replace('\033[31;1m','').replace('\033[0m','') if __name__=='__main__': logging.basicConfig(level=logging.DEBUG, format='%(message)s', filemode='w') logger=logging.getLogger(__name__) def parse_options(): usage = 'usage: %prog [Options]' parser = optparse.OptionParser() parser.add_option('-l', '--logfile', dest='logfile', help='use log file') opt,args = parser.parse_args() return opt,args opt,args=parse_options() if opt.logfile: class MyFormatter(logging.Formatter): def format(self,record): return plain(record.msg) fh = logging.FileHandler(opt.logfile) fh.setLevel(logging.INFO) formatter = MyFormatter('%(message)s') fh.setFormatter(formatter) logging.getLogger('').addHandler(fh) logger.info(error('There was a problem with the program')) logger.info("This is normal " + standout("and this stands out")) 

test.py is displayed only on the terminal.

test.py -l test.out prints both the terminal and the test.out file.

In all cases, the text on the terminal has color codes, but the journal does not.

+5
source share

unubtu answer below, but I think MyFormatter needs a little modification to allow formatting in the format () method

 class MyFormatter(logging.Formatter): def format(self,record): msg = super(MyFormatter, self).format(record) return plain(msg) 
+1
source share

All Articles