Python日志输出不同颜色字体并打印到日志文件

不管是客户端还是服务端,总是有大量的log在打印,想找到关键的几条真是不容易。调查了一下在Python里打印带颜色log的办法,这里应该是最简单的了,不需要任何外部库,并且Windows和Linux都支持。

使用方法

进入Python命令行,程序入口处执行个os.system(''),以后在想打印的字符两边插入几个特殊字符就可以了

这里,\033是八进制的27,也就是ASCII里的Escape。[31m指的是后面的东西变成红色,[0m指的是后面的东西恢复默认。 [32m指的是后面的东西变成绿色,[0m指的是后面的东西恢复默认。

需要注意的是,程序开始执行的时候,必须执行一下os.system(''),也就是执行一个空的cmd命令。如果不执行,会无法识别颜色指令。

基本颜色

\033[31m 看作\033[3xm,里面的x的取值范围是0到7,分别对应了

上图来在维基百科,直接搜“ansi escape code”就可以找到。

https://en.wikipedia.org/wiki/ANSI_escape_code​en.wikipedia.org

封装一下,就可以随意打印带颜色的log了!

原理

这些就是ANSI escape code,上面的百科网页里有详细说明。为啥是“escape”?就是这里的八进制\033,也就是十进制27,也就是十六进制0x1B,也就是ASCII里的Esc。 还有一个搜索关键字是 VT100 Emulation。

就是说,Console不只可以输出原始字符,还可以更改字符的格式,甚至操作光标之类。

其他使用方法

可以在cmd里直接echo出带颜色的字符串么?当然可以,但是,要学会输入Escape字符才行。本人试验必须是cmd,Powershell不行。

怎么输入escape呢?看上去有两种。第一种,按住Alt的时候按27,然后松开Alt;第二种,按Ctrl+[。

虽然显示的是个^[,但是,直接输入一个^一个[是不行的。

文本文件里可以么?虽然不能用编辑器直接查看,但是如果打印到命令行里,也是可以的。

打开Notepad++,输入

这个ESC怎么输入呢?找一个现成的复制,或者,按住Alt,按27,松开Alt,就会出来一个ESC了!ASCII里的其他控制字符也可以这样输入。

然后可以在命令行里打印

如果直接写在一个batch文件里,也可以这样echo带颜色的字符。

其他格式

仔细研究维基上的文章,还有不少其他的格式,刚才说的[3xm是前景色,还有[4xm是背景色,[9xm是明亮前景色 ,[10xm是明亮背景色。

这里有个脚本,打印了这4种模式 * 8种颜色的所有32种组合。

class Color:
    Black = 0
    Red = 1
    Green = 2
    Yellow = 3
    Blue = 4
    Magenta = 5
    Cyan = 6
    White = 7

class Mode:
    Foreground = 30
    Background = 40
    ForegroundBright = 90
    BackgroundBright = 100

def tcolor(c, m=Mode.Foreground):
    return '\033[{}m'.format(m + c)

def treset():
    return '\033[0m'

if __name__ == '__main__':
    import os
    os.system('')

    # usage
    print(tcolor(Color.Red) + 'hello' + treset())
    print(tcolor(Color.Green, Mode.Background) + 'color' + treset())
    print()

    COLOR_NAMES = ['Black', 'Red', 'Green', 'Yellow', 'Blue', 'Magenta', 'Cyan', 'White']
    MODE_NAMES = ['Foreground', 'Background', 'ForegroundBright', 'BackgroundBright']

    fmt = '{:11}' * len(COLOR_NAMES)
    print(' ' * 20 + fmt.format(*COLOR_NAMES))

    for mode_name in MODE_NAMES:
        print('{:20}'.format(mode_name), end='')
        for color_name in COLOR_NAMES:
            mode = getattr(Mode, mode_name)
            color = getattr(Color, color_name)
            print(tcolor(color, mode) + 'HelloColor' + treset(), end=' ')
        print()
 

在VSCode console里的输出

在Powershell里的输出

在cmd里的输出

在raspbian里的输出

正如维基里说的,不同的console,每种颜色对应的实际RGB值可能有出入。

实际上,还有高亮,划掉,下划线等等各种格式。可以仔细研究维基,或者看这里的一个脚本

win10colors.cmd

https://stackoverflow.com/questions/2048509/how-to-echo-with-different-colors-in-the-windows-command-line​stackoverflow.com

下面是这个win10colors.cmd前几行的输出,有粗体和下划线。

不同的console可能不会完全支持所有功能。

为什么需要os.system('')

如果不要这一句,Windows下颜色指令会不生效。其实,是利用了这句话的副作用,副作用就是执行cmd的时候,会打开VT100模拟。其实更“正确”的做法,是使用Windows提供的SetConsoleMode。

How to use the new support for ANSI escape sequences in the Windows 10 console?​stackoverflow.com图标

Linux不需要这个os.system('')

有兴趣的话可以找找IPython之类的库是怎么开启这个VT100模拟的。

其他

可以把print覆盖掉,或者封装几个print_infoprint_warningprint_error 之类的函数。

或者每个人使用自己的print函数,例如wyh_print,这样可以在本地自由开关所有人的 log,并且给自己加颜色,而不影响其他人。

如果可以和logging结合,配置不同级别,不同模块的log的颜色就太好了。

主要参考

https://stackoverflow.com/questions/287871/how-to-print-colored-text-in-terminal-in-python​stackoverflow.com

https://stackoverflow.com/questions/2048509/how-to-echo-with-different-colors-in-the-windows-command-line​stackoverflow.com

https://en.wikipedia.org/wiki/ANSI_escape_code​en.wikipedia.org

https://docs.microsoft.com/en-us/windows/console/setconsolemode?redirectedfrom=MSDN#ENABLE_VIRTUAL_TERMINAL_PROCESSING​docs.microsoft.com

Bonus

上面说的一堆,在IDLE是不生效的,但是IDLE里确实可以输出各种颜色。忘了在哪里抄的了,但是下面的代码可以在IDLE里打印颜色字符

import sys

try:
    shell = sys.stdout.shell
except AttributeError:
    raise RuntimeError("you must run this program in IDLE")

shell.write("Wanna go explore? ","KEYWORD")
shell.write("OPTIONS","STRING")
shell.write(" : ","KEYWORD")
shell.write("Yes","DEFINITION")
shell.write(" or ","KEYWORD")
shell.write("No","COMMENT")

print()
print("here are all the valid tags:\n")

valid_tags = ('SYNC', 'stdin', 'BUILTIN', 'STRING', 'console', 'COMMENT', 'stdout',
              'TODO','stderr', 'hit', 'DEFINITION', 'KEYWORD', 'ERROR', 'sel')

for tag in valid_tags:
    shell.write(tag+"\n",tag)
    

IDLE里的输出

发布于 2020-04-25

猜你喜欢

转载自blog.csdn.net/xcntime/article/details/115016933
今日推荐