Как раскрасить вывод ошибок Python в терминале Gnome?

Примечание. Я задаю этот вопрос после изучения того, как это сделать на самом деле. Другие вопросы, которые несколько похожи, но на самом деле отличаются от моего вопроса, относятся к:

  1. Цветовое кодирование внутри скрипта Python
  2. Импорт библиотек цветов внутри скрипта
  3. Использование таких инструментов, как Solarized, для улучшения таких инструментов, как Vim, для кодирования кода Python цветом.

Что мне нужно: у меня уже есть простой скрипт на Python (скажем, test.py), и я запускаю его из терминала Gnome.

python test.py

test.py выведет некоторые ошибки прямо в терминал. Пример ошибки:

Traceback (most recent call last):
  File "test.py", line 2, in <module>
    with open('', 'rb') as csvfile:
IOError: [Errno 2] No such file or directory: ''

Я хочу, чтобы ключевые слова ошибок были выделены, например, полужирным красным цветом, а номера строк — определенным цветом среди прочего, чтобы было легко отслеживать ошибки.

Как видите, Stackoverflow уже красиво кодирует ошибку цветом. На моем терминале Gnome вывод одноцветный. Как я могу получить такой красивый вывод с цветовой кодировкой на терминале?

Благодарю вас!


person Shailen    schedule 03.08.2014    source источник


Ответы (4)


Вы можете использовать раскраску IPython. Просто поместите это в начало вашей программы. Затем каждое исключение будет обработано ultratb и отображено в цвете, а также показаны значения locals() для фрагмента кода, вызвавшего исключение.

import sys
from IPython.core import ultratb
sys.excepthook = ultratb.FormattedTB(mode='Verbose', color_scheme='Linux', call_pdb=False)

Это будет работать, даже если вы вызовете свой скрипт с помощью интерпретатора vanilla python.

person Dorian B.    schedule 13.10.2018

Примечание. Не дает прямого ответа на вопрос выше, так как я плохо разбираюсь в sed. Но это улучшает читабельность, и по сравнению с другими, которые требуют ipython/медленны, это то, что я действительно использую регулярно.

Текущее (облегченное решение - например, не нужно ничего устанавливать и не нужно редактировать существующие файлы python один за другим)

Согласно https://stackoverflow.com/a/20910449, давайте использовать цветовые коды sed и ANSI.

Добавить в ~/.bashrc

norm="$(printf '\033[0m')" #returns to "normal"
bold="$(printf '\033[0;1m')" #set bold
red="$(printf '\033[0;31m')" #set red
boldyellowonblue="$(printf '\033[0;1;33;44m')" 
boldyellow="$(printf '\033[0;1;33m')"
boldred="$(printf '\033[0;1;31m')" #set bold, and set red.

copython() {
        python $@ 2>&1 | sed -e "s/Traceback/${boldyellowonblue}&${norm}/g" \
        -e "s/File \".*\.py\".*$/${boldyellow}&${norm}/g" \
        -e "s/\, line [[:digit:]]\+/${boldred}&${norm}/g"
    }

Перезагрузить

$ source ~/.bashrc

Как это выглядит изначально

$ python main.py

не окрашенная трассировка python в терминале

Довольно неприятно читать. Теперь сравните с

$ copython main.py

[раскрашенная трассировка Python в терминале

Это немного кричаще, но я доволен этим, и я не понимаю коды ANSI, поэтому я застрял на этих цветах :)


Примечание по цветовому коду ANSI

Обратите внимание, что \033[ отмечает начало кода, что помогло мне немного лучше понять, что происходит.

0m # normal
0;1m # bold 
0;1;33;44m # bold yellow on blue 
0;1;33m # bold yellow 
0;1;31m # bold red

Таким образом, я предполагаю, что первое 1 указывает жирный шрифт, затем второе 33 указывает цвет переднего плана, а третье 44 указывает цвет фона. Что-то подобное.


Устаревший

Я также искал что-то, где мне не нужно было изменять каждый отдельный файл Python, из которого я хочу печатать сообщения об ошибках. Как использовать ответ Тобина, я не сразу понял.

Для тех, кому интересно, как использовать, необходимо установить vimcat, затем добавить вышеуказанную функцию в bashrc (или другой файл, который вы используете) и запустить $ colorized test.py (вместо $ python test.py)

Например

~$ wget https://raw.githubusercontent.com/vim-scripts/vimcat/master/vimcat vimcat
~$ mv vimcat /usr/share/bin  # or /home/bin or wherever you want
~$ echo $PATH # make sure vimcat's directory is in your PATH variable, if not add to `~/.bashrc`
home/rui/.local/bin:/usr/local/sbin:/usr/share/bin
~$ source ~/.bashrc # reload PATH if had to add vimcat location
~$ vimcat somefile.sh # test that vimcat can be called
~$ colorized calibrate.py 

Как для меня выглядит до и после: до и после

И проверка того, что vimcat работает/получен правильно:

вимкэт

Обратите внимание, что это занимает заметно больше времени!

$ time colorized calibrate.py 
real    0m0.484s
user    0m0.392s
sys 0m0.085s

rui@chaiX1YG2:~$ $ time python calibrate.py 
real    0m0.343s
user    0m0.271s
sys 0m0.072s
person orangenarwhals    schedule 28.12.2019

Решение для быстрого взлома, только для UNIX. Перенаправить стандартный вывод в файл с суффиксом .py. Затем отобразите файл, используя vimcat для цветного вывода. Оберните все это в функции оболочки. Например, в Баше;

# print colorised python output
colorized() {
    local out='out.py'
    if (( $# < 1)) 
    then
        printf "Usage: %s pyhon-script\n" $0 >&2
        return 1;
    fi
    if [ -e $out ]; 
    then
        rm $out
    fi
    python $@ 2> $out
    empty=$(stat $out | grep empty)
    if (( $? == 1 ))
    then
        vimcat $out
    fi
}
person Tobin    schedule 01.12.2015

FWIW, вы можете обернуть скрипт в функцию main и вызвать функцию main в блоке try ... except, получить сообщение об ошибке, раскрасить его и распечатать;

Чтобы получить сообщение об ошибке, вам нужно вызвать sys.exc_info. traceback.format_exception форматирует трассировку стека и информацию об исключении. Используя базовое регулярное выражение, вы можете обернуть каждый ..Err.. внутри \033[91m...Err...\033[0m, который превращает цвет в красный:

def main():
   with open('xxx.txt', 'r') as fin:
        return fin.read()

try:
    main()
except:
    import re
    from sys import exc_info
    from traceback import format_exception

    RED, REV = r'\033[91m', r'\033[0m'
    err = ''.join(format_exception(*exc_info()))
    print(re.sub(r'(\w*Err\w*)', RED + r'\1' + REV, err))

Результат:

ошибка

person behzad.nouri    schedule 03.08.2014