Python:字典值中的八进制转义字符\ 033将print语句转换为UTF-8字符

Nic*_*las 9 python terminal dictionary escaping

我一直在终端和Python 2.7.3中尝试一些颜色输出.ANSI颜色代码总是在终端中完美呈现,有一个小例外,我无法确定任何精确程序,而不是这个特定的字典定义.

这是导致混淆的原因:

color = {
    'white':    "\033[1,37m",
    'yellow':   "\033[1,33m",
    'green':    "\033[1,32m",
    'blue':     "\033[1,34m",
    'cyan':     "\033[1,36m",
    'red':      "\033[1,31m",
    'magenta':  "\033[1,35m",
    'black':    "\033[1,30m",
    'darkwhite':  "\033[0,37m",
    'darkyellow': "\033[0,33m",
    'darkgreen':  "\033[0,32m",
    'darkblue':   "\033[0,34m",
    'darkcyan':   "\033[0,36m",
    'darkred':    "\033[0,31m",
    'darkmagenta':"\033[0,35m",
    'darkblack':  "\033[0,30m",
    'off':        "\033[0,0m"
}

yellow = "\033[1;33m"
off = "\033[0;0m"

print color['yellow'] + "string to render" + color['off']     # fails to render properly
print "%(yellow)sstring to render%(off)s" % color             # ditto
print "%sstring to render%s" % (color['yellow'], color['off'])# ditto

print yellow + "string to render" + off                       # as intended

pp = pprint.PrettyPrinter(indent=6)
pp.pprint(color)
Run Code Online (Sandbox Code Playgroud)

PrettyPrinter的输出:

{ 'black': '\x1b[1,30m',
  'blue': '\x1b[1,34m',
  'cyan': '\x1b[1,36m',
  'darkblack': '\x1b[0,30m',
  'darkblue': '\x1b[0,34m',
  'darkcyan': '\x1b[0,36m',
  'darkgreen': '\x1b[0,32m',
  'darkmagenta': '\x1b[0,35m',
  'darkred': '\x1b[0,31m',
  'darkwhite': '\x1b[0,37m',
  'darkyellow': '\x1b[0,33m',
  'green': '\x1b[1,32m',
  'magenta': '\x1b[1,35m',
  'off': '\x1b[0,0m',
  'red': '\x1b[1,31m',
  'white': '\x1b[1,37m',
  'yellow': '\x1b[1,33m'}
Run Code Online (Sandbox Code Playgroud)

在我看来,这是正确的十六进制格式转换.尽管如此,字典值仍未正确传递给print语句.原始和Unicode(绝望之外)字符串文字修饰符都不会改变任何东西.我必须遗漏一些相当明显的东西.在没有UTF-8支持的终端上,省略了Unicode字符.

我见过termcolor的实现 :

if os.getenv('ANSI_COLORS_DISABLED') is None:
    fmt_str = '\033[%dm%s'
    if color is not None:
        text = fmt_str % (COLORS[color], text)

    if on_color is not None:
        text = fmt_str % (HIGHLIGHTS[on_color], text)

    if attrs is not None:
        for attr in attrs:
            text = fmt_str % (ATTRIBUTES[attr], text)

    text += RESET
return text
Run Code Online (Sandbox Code Playgroud)

colorama:

CSI = '\033['
def code_to_chars(code):
    return CSI + str(code) + 'm'
class AnsiCodes(object):
    def __init__(self, codes):
        for name in dir(codes):
            if not name.startswith('_'):
                value = getattr(codes, name)
                setattr(self, name, code_to_chars(value))
Run Code Online (Sandbox Code Playgroud)

还有其他几个.从分析上讲,它们都避免在字典中定义整个序列.我确实同意这种方法在词汇上是合理的.然而事实仍然是字典值中的转义字符没有被正确解释,除了比如Perl哈希,C++的vectorized map <string, string>或C struct(如果类似于地图)char *string.

这导致了一个问题:如果可能的话,是否有一个特殊的原因,为什么字典(让我们配音这个:)插值偏离普通字符串?


这是固定颜色代码字典(如果编辑则标签缩进,SO似乎剥离标签字符以便阅读):

color = {
    'white':    "\033[1;37m",
    'yellow':   "\033[1;33m",
    'green':    "\033[1;32m",
    'blue':     "\033[1;34m",
    'cyan':     "\033[1;36m",
    'red':      "\033[1;31m",
    'magenta':  "\033[1;35m",
    'black':      "\033[1;30m",
    'darkwhite':  "\033[0;37m",
    'darkyellow': "\033[0;33m",
    'darkgreen':  "\033[0;32m",
    'darkblue':   "\033[0;34m",
    'darkcyan':   "\033[0;36m",
    'darkred':    "\033[0;31m",
    'darkmagenta':"\033[0;35m",
    'darkblack':  "\033[0;30m",
    'off':        "\033[0;0m"
}
Run Code Online (Sandbox Code Playgroud)

Pra*_*nde 7

我浏览了你的源代码,我认为probelm是在字典中的颜色定义.

如果仔细观察,颜色的字典值就像\ 033 [白色1,30米].但它应该是\ 033 [1; 30米.请注意,您使用的是' ,(逗号)字符而不是' ;(分号)字符.作为测试,我创建了颜色字典的子集并运行了这些测试.

>>> color = {'white' :'\033[1;37m', 'yellow':'\033[1;33m', 'off' : '\033[0;0m'}
>>> print color['white'] + 'string' + color['off']
string   #this string is white in color
>>> print color['yellow'] + 'string' + color['off']
string #this string is yellow in color
>>> color['yellow'] = '\033[1,33m' #incorrect color code - using a , character instead of ;
>>> print color['yellow'] + 'string' + color['off']
string   #prints the string in console default color i.e. not in yellow color
>>> 
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助