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

StackOverflow https://stackoverflow.com/questions/2893650

Вопрос

У меня есть следующие функции для окрашивания сообщений моего экрана:

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

Любой совет?

Это было полезно?

Решение

То 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

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

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

Другие советы

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

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.

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

Ответ ЮНУБТУ ниже отлично, но я думаю, что MyFormatter нуждается в незначительной модификации для обеспечения применения форматирования в формате ().

class MyFormatter(logging.Formatter):
        def format(self,record):
            msg = super(MyFormatter, self).format(record)
            return plain(msg)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top