2010-05-23 13 views
7

mi hanno le seguenti funzioni per colorare i miei messaggi su schermo:stampa STDOUT e file di log durante la rimozione codici colore ANSI

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

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

loro che uso come segue:

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

voglio registrare il output su un file (oltre a STDOUT) SENZA i codici colore ANSI, si spera senza aggiungere una seconda riga "logging" a ciascuna istruzione print.

Il motivo è che se si semplicemente python program.py > out il file out avrà i codici colore ANSI, che sembrano terribili se si apre in un editor di testo semplice.

Qualche consiglio?

risposta

9

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

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 

Che in realtà è uno dei pochi usi posso pensare di utilizzare un argomento di default non è impostato per None perché argomenti predefiniti vengono valutati in fase di compilazione tempo in Python piuttosto che in runtime come in C++ ...

Anche il comportamento può essere sovrascritto in modo esplicito se è davvero necessario, anche se questo non ti consente di manipolare lo stdout stesso quando viene reindirizzato. C'è qualche ragione per cui non stai usando il modulo logging (forse non lo sapevi)?

+0

risposta eccellente - questo potrebbe essere esattamente quello che mi serve. In realtà sto usando il modulo di registrazione, ma voglio lasciare all'utente la possibilità di reindirizzare l'output e ottenere un file leggibile dall'uomo. Il log stesso viene creato dal modulo di registrazione (e con il tuo approccio molto probabilmente otterrò quello che voglio). – Escualo

+0

Ho appena testato il tuo approccio e funziona esattamente come previsto. Grazie molto! – Escualo

5

Se si desidera stampare sia sul terminale che su un file di registro, suggerirei di utilizzare il modulo di registrazione. È anche possibile definire una formattazione personalizzata, in modo da accedere al file possibile eliminare i codici del 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")) 

test.py stampa solo al terminale.

test.py -l test.out stampe sul terminale e sul file test.out.

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

1

delle 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) 
Problemi correlati