使用utf8时,为什么在pprint显示时会将某些字符转换为\ u表示法?

时间:2017-01-01 06:00:47

标签: python python-3.x

这是一个控制台演示:

>>> x = "a b"
>>> x
'a\u200ab'
>>> repr( x )
"'a\\u200ab'"

所以看来pprint使用与打印字符串相同的技术。

不可否认,&和/或b在与x绑定的初始值中,确实是U + 200a。但是当使用UTF-8输入和输出编码时,为什么要将任何字符转换为\ u表示输出?

问题2当然是如何才能了解到以这种方式转换的整个字符集是什么?

问题3当然是如何抑制这种行为?

2 个答案:

答案 0 :(得分:3)

pprint打印传递它的对象的表示形式。来自the docs

  

pprint模块提供了“漂亮”打印任意的功能   Python数据结构的形式可以用作输入   解释

和"一种可用作解释器输入的表格"表示您获得对象的表示,即其__repr__方法返回的内容。

如果您希望使用__str__方法而不是__repr__方法打印字符串,请不要使用pprint

这是一个Python 3代码段,用于查找使用\u转义码表示的字符:

for i in range(1500):
    c = chr(i)
    r = repr(c)
    if r'\u' in r:
        print('{0:4} {0:04x} {1} {2}'.format(i, r, c))

<强>输出

 888 0378 '\u0378' ͸
 889 0379 '\u0379' ͹
 896 0380 '\u0380' ΀
 897 0381 '\u0381' ΁
 898 0382 '\u0382' ΂
 899 0383 '\u0383' ΃
 907 038b '\u038b' ΋
 909 038d '\u038d' ΍
 930 03a2 '\u03a2' ΢
1328 0530 '\u0530' ԰
1367 0557 '\u0557' ՗
1368 0558 '\u0558' ՘
1376 0560 '\u0560' ՠ
1416 0588 '\u0588' ֈ
1419 058b '\u058b' ֋
1420 058c '\u058c' ֌
1424 0590 '\u0590' ֐
1480 05c8 '\u05c8' ׈
1481 05c9 '\u05c9' ׉
1482 05ca '\u05ca' ׊
1483 05cb '\u05cb' ׋
1484 05cc '\u05cc' ׌
1485 05cd '\u05cd' ׍
1486 05ce '\u05ce' ׎
1487 05cf '\u05cf' ׏

请注意,代码点&gt;必要时,使用\U转义码表示0xffff。

for i in range(65535, 65600):
    c = chr(i)
    r = repr(c)
    if r'\u' in r.lower():
        print('{0:4} {0:04x} {1} {2}'.format(i, r, c))

<强>输出

65535 ffff '\uffff' �
65548 1000c '\U0001000c' 
65575 10027 '\U00010027' 
65595 1003b '\U0001003b' 
65598 1003e '\U0001003e' 

答案 1 :(得分:1)

我终于找到了解释它的文档。 来自Python Unicode documentation

int Py_UNICODE_ISPRINTABLE(Py_UNICODE ch)

Return 1 or 0 depending on whether ch is a printable character. Nonprintable characters are those characters defined in the Unicode character database as “Other” or “Separator”, excepting the ASCII space (0x20) which is considered printable. (Note that printable characters in this context are those which should not be escaped when repr() is invoked on a string. It has no bearing on the handling of strings written to sys.stdout or sys.stderr.)

它部分回答了第一个问题(事实,而不是原因),并得出问题2的确切答案。

Unicode space separator characters

我认为在视觉上毫不含糊的愿望是事实的原因......所有这些分隔符都看起来“相同”(白色空间)。如果您正在检查纸质日志,这可能很重要,但如果在线检查,复制/粘贴到十六进制显示工具,或This wonderfully helpful Unicode decoder肯定是足够的,而不会在文本的细节流动时中断使用分隔符并不重要(在我看来,这是大部分非纸质时间)。

问题3显然可以通过以下两种方式之一完成:使用不同的 repr 创建str的子类(破坏现有代码)或使用格式函数创建pprint的子类,以避免调用< str> strong> repr ,但只是直接包含该值。