Skip to main content
 首页 » 编程设计

python之彩色终端库

2025年05月04日1152php

我正在尝试用 Python 在我的文本上实现颜色循环...由于上下文发生了巨大变化,这个问题已被编辑并作为另一个问题重新提交。请参阅here相反。

这个问题更多是关于我应该使用什么库 - termcolor , colorama , curses和一个 ansi colour recipe ,

到目前为止的代码:

#!/usr/bin/env python 
 
''' 
        "arg" is a string or None 
        if "arg" is None : the terminal is reset to his default values. 
        if "arg" is a string it must contain "sep" separated values. 
        if args are found in globals "attrs" or "colors", or start with "@" \ 
    they are interpreted as ANSI commands else they are output as text. 
        @* commands: 
 
            @x;y : go to xy 
            @    : go to 1;1 
            @@   : clear screen and go to 1;1 
        @[colour] : set foreground colour 
        ^[colour] : set background colour 
 
        examples: 
    echo('@red')                  : set red as the foreground color 
    echo('@red ^blue')             : red on blue 
    echo('@red @blink')            : blinking red 
    echo()                       : restore terminal default values 
    echo('@reverse')              : swap default colors 
    echo('^cyan @blue reverse')    : blue on cyan <=> echo('blue cyan) 
    echo('@red @reverse')          : a way to set up the background only 
    echo('@red @reverse @blink')    : you can specify any combinaison of \ 
            attributes in any order with or without colors 
    echo('@blink Python')         : output a blinking 'Python' 
    echo('@@ hello')             : clear the screen and print 'hello' at 1;1 
 
colours: 
{'blue': 4, 'grey': 0, 'yellow': 3, 'green': 2, 'cyan': 6, 'magenta': 5, 'white': 7, 'red': 1} 
 
    ''' 
 
''' 
    Set ANSI Terminal Color and Attributes. 
''' 
from sys import stdout 
import random 
import sys 
import time 
 
esc = '%s['%chr(27) 
reset = '%s0m'%esc 
format = '1;%dm' 
fgoffset, bgoffset = 30, 40 
for k, v in dict( 
    attrs = 'none bold faint italic underline blink fast reverse concealed', 
    colours = 'grey red green yellow blue magenta cyan white' 
).items(): globals()[k]=dict((s,i) for i,s in enumerate(v.split())) 
 
def echo(arg=None, sep=' ', end='\n', rndcase=True, txtspeed=0.03): 
 
    cmd, txt = [reset], [] 
    if arg: 
        # split the line up into 'sep' seperated values - arglist 
            arglist=arg.split(sep) 
 
        # cycle through arglist - word seperated list  
            for word in arglist: 
 
                if word.startswith('@'): 
            ### First check for a colour command next if deals with position ### 
                # go through each fg and bg colour   
                tmpword = word[1:] 
                    if tmpword in colours: 
                        cmd.append(format % (colours[tmpword]+fgoffset)) 
                    c=format % attrs[tmpword] if tmpword in attrs else None 
                    if c and c not in cmd: 
                                cmd.append(c) 
                    stdout.write(esc.join(cmd)) 
                    continue 
                # positioning (starts with @) 
                word=word[1:] 
                if word=='@': 
                    cmd.append('2J') 
                    cmd.append('H') 
                    stdout.write(esc.join(cmd)) 
                    continue 
                else: 
                    cmd.append('%sH'%word) 
                    stdout.write(esc.join(cmd)) 
                    continue 
 
                if word.startswith('^'): 
            ### First check for a colour command next if deals with position ### 
                # go through each fg and bg colour   
                tmpword = word[1:] 
                    if tmpword in colours: 
                        cmd.append(format % (colours[tmpword]+bgoffset)) 
                    c=format % attrs[tmpword] if tmpword in attrs else None 
                    if c and c not in cmd: 
                                cmd.append(c) 
                    stdout.write(esc.join(cmd)) 
                    continue                     
            else: 
                for x in word:   
                    if rndcase: 
                        # thankyou mark! 
                        if random.randint(0,1): 
                                x = x.upper() 
                        else: 
                            x = x.lower() 
                    stdout.write(x) 
                    stdout.flush() 
                    time.sleep(txtspeed) 
                stdout.write(' ') 
                time.sleep(txtspeed) 
    if txt and end: txt[-1]+=end 
    stdout.write(esc.join(cmd)+sep.join(txt)) 
 
if __name__ == '__main__': 
 
    echo('@@') # clear screen 
    #echo('@reverse') # attrs are ahem not working 
    print 'default colors at 1;1 on a cleared screen' 
    echo('@red hello this is red') 
    echo('@blue this is blue @red i can ^blue change @yellow blah @cyan the colours in ^default the text string') 
    print 
    echo() 
    echo('default') 
    echo('@cyan ^blue cyan blue') 
#   echo('@cyan ^blue @reverse cyan blue reverse') 
#   echo('@blue ^cyan blue cyan') 
    #echo('@red @reverse red reverse') 
#    echo('yellow red yellow on red 1') 
#    echo('yellow,red,yellow on red 2', sep=',') 
#    print 'yellow on red 3' 
 
#        for bg in colours: 
#                echo(bg.title().center(8), sep='.', end='') 
#                for fg in colours: 
#                        att=[fg, bg] 
#                        if fg==bg: att.append('blink') 
#                        att.append(fg.center(8)) 
#                        echo(','.join(att), sep=',', end='') 
 
    #for att in attrs: 
    #   echo('%s,%s' % (att, att.title().center(10)), sep=',', end='') 
    #   print 
 
    from time import sleep, strftime, gmtime 
    colist='@grey @blue @cyan @white @cyan @blue'.split() 
    while True: 
        try: 
            for c in colist: 
                sleep(.1) 
                echo('%s @28;33 hit ctrl-c to quit' % c,txtspeed=0) 
            #echo('@yellow @6;66 %s' % strftime('%H:%M:%S', gmtime())) 
        except KeyboardInterrupt: 
            break 
        except: 
            raise 
    echo('@10;1') 
    print 

请您参考如下方法:

这里有一些可以尝试的技巧:

  1. 此代码块创建实际转义字符串列表。它使用 list comprehension遍历颜色名称列表并在 colour 字典中查找转义码。 .split() 只是一种创建字符串列表的惰性方法,无需键入大量引号-逗号-引号序列。

    color_cycle = [ 
        [colour[name] for name in 'bldylw bldred bldgrn bldblu txtwht'.split()], 
        [colour[name] for name in 'txtblu txtcyn'.split()] 
    ] 
    
  2. 稍后,您的函数可以通过创建 iterator 来使用这些列表.这个特定的迭代器使用标准库函数 itertools.cycle ,无限重复一个序列。我在这里假设您想用不同的颜色书写字符串的每个字符。

    import itertools 
     
    # Create an iterator for the selected color sequence. 
    if colourc: 
        icolor = itertools.cycle(color_cycle[colourc - 1]) 
     
    for a in stringy: 
        # Write out the escape code for next color 
        if colourc: 
            color = next(icolor) 
            sys.stdout.write(color) 
    
  3. 这是另一种选择随机大小写的方法。在 Python 中,零被认为是错误的:

        if rndcase: 
            if random.randint(0,1): 
                a = a.upper() 
            else: 
                a = a.lower()