Python 拉丁字符与Unicode

1 投票
2 回答
11877 浏览
提问于 2025-04-18 03:45

我有一个树形结构,其中的关键词可能包含一些拉丁字符。我有一个函数,它会遍历树的所有叶子节点,并在满足某些条件时将每个关键词添加到一个列表中。

这是我用来将这些关键词添加到列表中的代码:

print "Adding: " + self.keyword
leaf_list.append(self.keyword)
print leaf_list

如果这个关键词是 université,那么我的输出是:

Adding: université
['universit\xc3\xa9']

看起来打印函数可以正确显示拉丁字符,但当我把它添加到列表时,它却被解码了。

我该如何改变这个情况?我需要能够打印出包含标准拉丁字符的列表,而不是它们的解码版本。

2 个回答

0

当你打印一个列表时,你看到的是列表里面每个项目的repr,对于字符串来说,这个repr和它们实际的内容是不同的:

>>> a = ['foo', 'bär']
>>> print(a[0])
foo
>>> print(repr(a[0]))
'foo'
>>> print(a[1])
bär
>>> print(repr(a[1]))
'b\xc3\xa4r'

repr的输出是为了程序员方便看的,而不是普通用户方便看的,所以它会显示引号和十六进制代码。如果你想以更友好的方式打印一个列表,可以自己写一个循环。例如:

>>> print '[', ', '.join(a), ']'
[ foo, bär ]
3

你现在手里没有Unicode对象,而是一些用UTF-8编码的字节字符串。如果你的终端设置支持UTF-8文本,打印这些字节字符串可能会正常工作。

当你把一个列表转换成字符串时,列表里的内容会以一种“表现形式”显示出来,这就是repr()函数的结果。字符串对象的表现形式会用转义码来表示那些不在可打印ASCII范围内的字节;比如换行符会被替换成\n。你的UTF-8字节会用\xhh这样的转义序列来表示。

如果你使用的是Unicode对象,表现形式仍然会用\xhh转义,但只针对拉丁-1范围内的Unicode码点(也就是不在ASCII范围内的部分);其他的则会用\uhhhh\Uhhhhhhhh来表示,具体取决于它们的码点。当打印时,Python会自动将这些值编码成你终端所需的正确编码:

>>> u'université'
u'universit\xe9'
>>> len(u'université')
10
>>> print u'université'
université

再来看看字节字符串:

>>> 'université'
'universit\xc3\xa9'
>>> len('université')
11
>>> 'université'.decode('utf8')
u'universit\xe9'
>>> print 'université'
université

注意,é这个码点的长度也反映出它被编码成了两个字节。顺便说一下,当我把é字符粘贴到Python会话中时,是我的终端把\xc3\xa9字节提供给了Python,因为它被设置为使用UTF-8,而Python在我定义u'..'这个Unicode对象字面量时检测到了这一点并解码了这些字节。

我强烈建议你阅读以下文章,以了解Python如何处理Unicode,以及Unicode文本和编码字节字符串之间的区别:

撰写回答