Domanda

Ho le seguenti funzioni per colorare i miei messaggi su schermo:

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

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

li uso come segue:

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

Voglio registrare l'output in un file (in aggiunta a STDOUT) SENZA i codici colore ANSI, si spera senza dover aggiungere un secondo "logging" linea ad ogni dichiarazione print.

La ragione è che se semplicemente python program.py > out quindi il file out avrà i codici colore ANSI, che sembrano terribile se si apre in un editor di testo.

Qualche consiglio?

È stato utile?

Soluzione

La funzione sys.stdout.isatty potrebbe essere in grado di aiuto:

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

Questo è in realtà uno dei pochi usi posso pensare di utilizzare un argomento di default non è impostato per None perché argomenti predefiniti vengono valutati al momento della compilazione in Python, piuttosto che a runtime come in C ++ ...

Anche il comportamento può essere sovrascritto in modo esplicito se si ha realmente bisogno di, anche se questo non consente di manipolare stdout sé quando è reindirizzato. C'è qualche motivo per cui non si sta usando il modulo logging (forse non lo sapevate su di esso)?

Altri suggerimenti

Se si desidera stampare sia al terminale e ad un file di log, quindi suggerirei utilizzando il modulo di registrazione. È anche possibile definire una formattazione personalizzata, in modo registrazione per il file può eliminare i codici di terminale:

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

solo stampe test.py al terminale.

stampe test.py -l test.out sia al terminale e al file test.out.

In tutti i casi, il testo al terminale ha codici di colore, mentre la registrazione non ne ha.

La risposta di unubtu sotto è grande, ma credo che MyFormatter ha bisogno di una piccola modifica per far rispettare la formattazione nel metodo format ()

class MyFormatter(logging.Formatter):
        def format(self,record):
            msg = super(MyFormatter, self).format(record)
            return plain(msg)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top