彩色的print接口

-- TOC --

本文总结一些print函数接口的使用知识。

彩色打印

这是一个自己积累的接口函数,可以方便的在命令行输出彩色的文字。

def cprint(*objects, sep=' ', end='\n', file=sys.stdout,
           flush=False, fg=None, bg=None, style='default'):
    """colorful print.
    Color and style the string and background, then call the print function,
    Eg: cprint('pynote.net', fg='red', bg='green', style='blink')
    The other parameters are the same with stand print!
    """
    def _ct(code='0'):
        return '\033[%sm'%code

    # text color
    c = 37
    if fg in ('red','r'): c = 31
    elif fg in ('green','g'): c = 32
    elif fg in ('yellow','y'): c = 33
    elif fg in ('blue','b'): c = 34
    elif fg in ('magenta','m'): c = 35
    elif fg in ('cyan','c'): c = 36
    elif fg in ('white','w'): c = 37
    elif fg in ('black','k'): c = 30
    # background color
    b = 40
    if bg in ('red','r'): b = 41
    elif bg in ('green','g'): b = 42
    elif bg in ('yellow','y'): b = 43
    elif bg in ('blue','b'): b = 44
    elif bg in ('magenta','m'): b = 45
    elif bg in ('cyan','c'): b = 46
    elif bg in ('white','w'): b = 47
    elif bg in ('black','k'): b = 40
    # style
    a = 0
    if style == 'underline': a = 4
    elif style == 'blink': a = 5
    elif style == 'inverse': a = 7

    string = sep.join(map(str, objects))
    color = '%d;%d;%d' % (a,c,b)
    print(_ct(color)+string+_ct(), sep=sep, end=end, file=file, flush=flush)

花梢的东西,不要花费太多时间,玩玩即可。

原理和echo命令彩色输出一样。

输出声音

>>> print('\a')

python3的print是线程安全的

在多线程的场景下,使用print输出,心中总是有个疑惑,多线程切换时,是否会导致打印输出混乱?搜索了一番后,这个问题有了结论,python2的print是线程不安全的,多线程打印输出会造成混乱;而python3的print是线程安全的,多线程打印输出不会造成混乱!

2020年python基金会就不再维护python2了,其print的线程不安全,我就不纠结了。

我们可以写一个python3多线程的测试程序,来观察print的输出是否会混乱。下面是我自己写的一段代码:

import time
import threading

def a():
    time.sleep(0.1)
    print('hello 12345')

ts = []
for i in range(100):
    t = threading.Thread(target=a)
    t.start()

反复测试了好几遍,没有观察到打印混乱的情况出现。

另一个方法是看看python的bytecode:

>>> def a():
...     print('hello')
...
>>> dis.dis(a)
  2           0 LOAD_GLOBAL              0 (print)
              2 LOAD_CONST               1 ('hello')
              4 CALL_FUNCTION            1
              6 POP_TOP
              8 LOAD_CONST               0 (None)
             10 RETURN_VALUE

CALL_FUNCTION就是调用print,这是一句python3虚拟机的opcode,因此是原子操作,因此print是线程安全的!

在python2中,可以使用sys.stdout.write来代替print,实现线程安全的原子打印输出。

用print在CLI界面打印进度条

import time


def progress(percent=0, width=30):
    left = width * percent // 100
    right = width - left
    print('\r[', '#' * left, ' ' * right, ']',
          f' {percent:.0f}%',
          sep='', end='', flush=True)


for i in range(101):
    progress(i)
    time.sleep(0.1)

\r也可以实现原地打印!

直接向stderr输出

print('-'*40, file=sys.stderr)
print('Exception occurred during processing of request from',
            client_address, file=sys.stderr)

本文链接:https://cs.pynote.net/sf/python/202203133/

-- EOF --

-- MORE --