2010-05-23 16 views
7

que tienen las siguientes funciones para colorear mis mensajes en la pantalla:impresión en STDOUT y el archivo de registro mientras se quita los códigos de color ANSI

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

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

Las uso de la siguiente manera:

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

que quieren registrar el salida a un archivo (además de STDOUT) SIN los códigos de color ANSI, con suerte sin tener que agregar una segunda línea de "registro" a cada declaración print.

La razón es que si simplemente python program.py > out el archivo out tendrá los códigos de color ANSI, que se ven terribles si se abre en un editor de texto sin formato.

¿Algún consejo?

Respuesta

9

La función sys.stdout.isatty podría ser capaz de ayudar:

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 

que en realidad es uno de los pocos usos que se me ocurre para usar un argumento predeterminado que no se ajusta a None porque los argumentos por defecto son evaluados en tiempo de compilación tiempo en Python en lugar de en tiempo de ejecución como en C++ ...

También el comportamiento se puede anular explícitamente si realmente lo necesita, aunque eso no le permite manipular stdout en sí mismo cuando se redirige. ¿Hay alguna razón por la que no está utilizando el módulo logging (quizás no lo sabía)?

+0

excelente respuesta - esto puede ser exactamente lo que necesito. De hecho, estoy usando el módulo de registro, pero quiero dejar que el usuario tenga la opción de redirigir el resultado y obtener un archivo legible por humanos. El registro en sí mismo es creado por el módulo de registro (y con su enfoque, lo más probable es que obtenga lo que quiero). – Escualo

+0

Acabo de probar su enfoque y funciona exactamente como se esperaba. ¡Muchas gracias! – Escualo

5

Si desea imprimir tanto en el terminal como en un archivo de registro, le sugiero que utilice el módulo de registro. Incluso puede definir un formateador personalizado, por lo que el registro en el archivo puede purgar los códigos de terminal:

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 imprime sólo al terminal.

test.py -l test.out imprime tanto en el terminal como en el archivo test.out.

En todos los casos, el texto del terminal tiene códigos de color, mientras que el registro no tiene ninguno. respuesta

1

de unubtu a continuación es grande, pero creo que myFormatter necesita una pequeña modificación para hacer cumplir el formato en el método format()

class MyFormatter(logging.Formatter): 
     def format(self,record): 
      msg = super(MyFormatter, self).format(record) 
      return plain(msg) 
Cuestiones relacionadas