Печать к STDOUT и файлу журнала при удалении цветовых кодов ANSI

У меня есть следующие функции для колоризации мои экранные сообщения:

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

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

Я использую их следующим образом:

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

Я хочу зарегистрировать вывод в файл (в дополнение к STDOUT) БЕЗ цветовых кодов ANSI, надо надеяться, не имея необходимость добавлять вторую строку "входа" к каждому print оператор.

Причина состоит в том что если Вы просто python program.py > out затем файл out будет иметь цветовые коды ANSI, которые выглядят ужасными, если Вы открываетесь в редакторе простого текста.

Совет?

7
задан Escualo 23 May 2010 в 22:00
поделиться

2 ответа

Функция sys.stdout.isatty могла бы помочь:

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

На самом деле это одно из немногих вариантов использования аргумента по умолчанию, который не 'не установлено значение Нет , потому что аргументы по умолчанию оцениваются во время компиляции в Python, а не во время выполнения, как в C ++ ...

Также поведение может быть явно переопределено, если вам действительно нужно, хотя это не не позволяю вам манипулировать самим stdout, когда он перенаправлен. Есть ли причина, по которой вы не используете модуль logging (возможно, вы не знали об этом)?

10
ответ дан 6 December 2019 в 11:46
поделиться

Если вы хотите печатать как на терминал, так и в файл журнала, я бы предложил использовать модуль регистрации. Вы даже можете определить пользовательский форматтер, так что запись в файл может очистить коды терминала:

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 выводится только на терминал.

test.py -l test.out выводится как на терминал, так и в файл test.out .

Во всех случаях текст для терминала имеет цветовые коды, а в журнале нет.

6
ответ дан 6 December 2019 в 11:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: