什么是Unicode字符串?

36

什么是Unicode字符串?

普通字符串和Unicode字符串有什么区别?

UTF-8是什么?

我正在学习Python,经常听到这个词。下面的代码是做什么的?

i18n字符串(Unicode)

> ustring = u'A unicode \u018e string \xf1'
> ustring
u'A unicode \u018e string \xf1'

## (ustring from above contains a unicode string)
> s = ustring.encode('utf-8')
> s
'A unicode \xc6\x8e string \xc3\xb1'  ## bytes of utf-8 encoding
> t = unicode(s, 'utf-8')             ## Convert bytes back to a unicode string
> t == ustring                      ## It's the same as the original, yay!
True

文件的Unicode编码

import codecs

f = codecs.open('foo.txt', 'rU', 'utf-8')
for line in f:
# here line is a *unicode* string

4
互联网搜索可能是一个很好的开始地方... - Mitch Wheat
可能是Python中的Unicode的重复问题。 - tripleee
请参见http://bit.ly/unipain。 - tripleee
2个回答

59

更新:Python 3

在Python 3中,默认使用Unicode字符串。类型str是Unicode代码点的集合,而类型bytes用于表示8位整数的集合(通常被解释为ASCII字符)。

以下是针对Python 3更新的问题代码:

>>> my_str = 'A unicode \u018e string \xf1' # no need for "u" prefix
# the escape sequence "\u" denotes a Unicode code point (in hex)
>>> my_str
'A unicode Ǝ string ñ'
# the Unicode code points U+018E and U+00F1 were displayed
# as their corresponding glyphs
>>> my_bytes = my_str.encode('utf-8') # convert to a bytes object
>>> my_bytes
b'A unicode \xc6\x8e string \xc3\xb1'
# the "b" prefix means a bytes literal
# the escape sequence "\x" denotes a byte using its hex value
# the code points U+018E and U+00F1 were encoded as 2-byte sequences
>>> my_str2 = my_bytes.decode('utf-8') # convert back to str
>>> my_str2 == my_str
True

文件操作:

>>> f = open('foo.txt', 'r') # text mode (Unicode)
>>> # the platform's default encoding (e.g. UTF-8) is used to decode the file
>>> # to set a specific encoding, use open('foo.txt', 'r', encoding="...")
>>> for line in f:
>>>     # here line is a str object

>>> f = open('foo.txt', 'rb') # "b" means binary mode (bytes)
>>> for line in f:
>>>     # here line is a bytes object

历史回答:Python 2

在 Python 2 中,str 类型是由 8 位字符组成的集合(类似于 Python 3 的 bytes 类型)。英文字母可以用这些 8 位字符表示,但是像 Ω、и、± 和 ♠ 这样的符号就不行了。

Unicode 是一种处理广泛字符集的标准。每个符号都有一个码点(一个数字),这些码点可以使用多种编码(转换为字节序列)进行编码。

UTF-8 就是这样一种编码方式。低码点使用单个字节编码,高码点则编码为字节序列。

为了让 Python 2 能够处理 Unicode 字符,它有一个 unicode 类型,该类型是 Unicode 码点的集合(类似于 Python 3 的 str 类型)。语句 ustring = u'A unicode \u018e string \xf1' 创建了一个包含 20 个字符的 Unicode 字符串。

当 Python 解释器显示 ustring 的值时,它会对两个字符(Ǝ 和 ñ)进行转义,因为它们不在标准可打印范围内。

语句 s = unistring.encode('utf-8') 使用 UTF-8 编码 Unicode 字符串。这将每个码点转换为相应的字节或字节序列。结果是一组字节,作为 str 返回。 s 的大小为 22 个字节,因为其中有两个字符具有高码点,并被编码为两个字节序列而不是单个字节。

当 Python 解释器显示 s 的值时,它会对不在可打印范围内的四个字节进行转义(\xc6\x8e\xc3\xb1)。由于 sstr 类型而不是 unicode,所以两个字节对不像之前那样被视为单个字符。

语句 t = unicode(s, 'utf-8') 执行与 encode() 相反的操作。它通过查看 s 的字节并解析字节序列来重新构建原始码点。结果是一个 Unicode 字符串。

调用 codecs.open() 指定 utf-8 作为编码方式,告诉 Python 将文件的内容(一组字节)解释为使用 UTF-8 编码的 Unicode 字符串。


2
更具体地说,上述内容适用于Python v2。在Python v3中,Unicode字符串是默认设置。 - tripleee
谢谢,但我们什么时候才能真正“看到”那些Unicode字符呢?我们会将我们的Python代码“注入”到能够显示它们的系统中吗? - aderchox
1
通常现在,如果您只是将字符串打印到控制台输出,或将其写入文件,然后在编辑器中查看,您将能够看到任何非ASCII字符。由于UTF8基本上与ASCII向后兼容,大多数系统现在应默认假定UTF8编码。(出于同样的原因,您应该能够直接将Unicode字符保存到您的.py文件中,并跳过转义表示。)@aderchox - benjimin

-5

Python支持字符串类型和Unicode类型。字符串是字符序列,而Unicode是“指针”序列。Unicode是序列的内存表示形式,它上面的每个符号都不是一个字符,而是一个数字(以十六进制格式),用于在映射中选择一个字符。因此,Unicode变量没有编码,因为它不包含字符。


1
你可以在这篇博客中详细了解它: http://www.carlosble.com/2010/12/understanding-python-and-unicode/ - Renjith Nair
4
不准确的答案。那些不是“指针”,两种类型都用于表示字符串。 - tripleee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接