更新: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 就是这样一种编码。低码位使用单个字节编码,高码点编码为字节序列。
为了允许使用 Unicode 字符,Python 2 有一个 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)。这两对字节不像以前那样被视为单个字符,因为s 的类型是str,而不是unicode。
t = unicode(s, 'utf-8') 行与encode() 正好相反。它通过查看s 的字节并解析字节序列来重构原始代码点。结果是一个 Unicode 字符串。
对codecs.open() 的调用将utf-8 指定为编码,这告诉Python 将文件的内容(字节集合)解释为使用UTF-8 编码的Unicode 字符串。