Question

Je possède les fonctions suivantes pour colorisation mes messages d'écran:

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

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

Je les utilise comme suit:

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

Je veux connecter la sortie vers un fichier (en plus de STDOUT) sans les codes couleurs ANSI, je l'espère, sans avoir à ajouter un deuxième « exploitation forestière » ligne à chaque instruction print.

La raison est que si vous python program.py > out simplement le fichier out aura les codes couleurs ANSI, qui ont l'air terribles si vous ouvrez dans un éditeur de texte brut.

Un conseil?

Était-ce utile?

La solution

La fonction sys.stdout.isatty pourrait être en mesure d'aider:

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

C'est en fait l'un des rares utilisations que je peux penser à utiliser un argument par défaut qui n'est pas réglé sur None parce que les arguments par défaut sont évalués au moment de la compilation en Python plutôt que lors de l'exécution comme en C ++ ...

De plus, le comportement peut être explicitement annulé si vous avez vraiment besoin, si cela ne vous laissez pas manipuler lui-même stdout quand il est redirigé. Y at-il des raisons pour lesquelles vous ne l'utilisez le module logging (peut-être vous ne saviez pas à ce sujet)?

Autres conseils

Si vous souhaitez imprimer à la fois le terminal et à un fichier journal, alors je suggère d'utiliser le module de journalisation. Vous pouvez même définir une mise en forme personnalisée, de sorte que l'enregistrement au fichier peut purger les codes terminaux:

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

imprime test.py uniquement au terminal.

imprime test.py -l test.out à la fois le terminal et le fichier test.out.

Dans tous les cas, le texte au terminal a des codes de couleur, alors que l'enregistrement a pas.

La réponse de unubtu ci-dessous est grande, mais je pense que MyFormatter a besoin d'une modification mineure pour appliquer le formatage dans la méthode format ()

class MyFormatter(logging.Formatter):
        def format(self,record):
            msg = super(MyFormatter, self).format(record)
            return plain(msg)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top