字符串字节与 Unicode

Python 2.x <= 2.7

在 Python 2 中,有两种字符串变体:由字节类型( str )组成的字符串和由类型( unicode )的文本组成的字符串

在 Python 2 中,str 类型的对象始终是字节序列,但通常用于文本和二进制数据。

字符串文字被解释为字节字符串。

s = 'Cafe'    # type(s) == str

有两个例外:你可以通过在文字前加上 u 来明确定义 Unicode(文本)文字

s = u'Café'   # type(s) == unicode
b = 'Lorem ipsum'  # type(b) == str

或者,你可以指定整个模块的字符串文字应创建 Unicode(文本)文字:

from __future__ import unicode_literals

s = 'Café'   # type(s) == unicode
b = 'Lorem ipsum'  # type(b) == unicode

为了检查你的变量是否是字符串(Unicode 或字节字符串),你可以使用:

isinstance(s, basestring)

Python 3.x >= 3.0

在 Python 3 中,str 类型是 Unicode 文本类型。

s = 'Cafe'           # type(s) == str
s = 'Café'           # type(s) == str (note the accented trailing e)

此外,Python 3 添加了一个 bytes 对象 ,适用于二进制 blob 或写入与编码无关的文件。要创建字节对象,可以将 b 作为字符串文字的前缀或调用字符串的 encode 方法:

# Or, if you really need a byte string:
s = b'Cafe'          # type(s) == bytes
s = 'Café'.encode()  # type(s) == bytes

要测试值是否为字符串,请使用:

isinstance(s, str)

Python 3.x >= 3.3

也可以在字符串文字前加上 u 前缀,以简化 Python 2 和 Python 3 代码库之间的兼容性。因为在 Python 3 中,默认情况下所有字符串都是 Unicode,所以使用 u 预先添加字符串文字无效:

u'Cafe' == 'Cafe'

不支持 Python 2 的原始 Unicode 字符串前缀 ur

>>> ur'Café'
  File "<stdin>", line 1
    ur'Café'
           ^
SyntaxError: invalid syntax

请注意,你必须 encode 一个 Python 3 文本(str)对象将其转换成文本的 bytes 表示。此方法的默认编码为 UTF-8

你可以使用 decodebytes 对象询问它所代表的 Unicode 文本:

>>> b.decode()
'Café'

Python 2.x >= 2.6

虽然 bytes 类型同时存在于 Python 2 和 3 中,但 unicode 类型仅存在于 Python 2 中。要在 Python 2 中使用 Python 3 的隐式 Unicode 字符串,请将以下内容添加到代码文件的顶部:

from __future__ import unicode_literals
print(repr("hi"))
# u'hi'

Python 3.x >= 3.0

另一个重要的区别是 Python 3 中的索引字节会导致 int 输出,如下所示:

b"abc"[0] == 97

虽然切片大小为 1 会导致长度为 1 个字节的对象:

b"abc"[0:1] == b"a"

此外,Python 3 使用 unicode 修复了一些异常行为 ,即在 Python 2 中反转字节字符串。例如,解决了以下问题

# -*- coding: utf8 -*-
print("Hi, my name is Łukasz Langa.")
print(u"Hi, my name is Łukasz Langa."[::-1])
print("Hi, my name is Łukasz Langa."[::-1])

# Output in Python 2
# Hi, my name is Łukasz Langa.
# .agnaL zsakuŁ si eman ym ,iH
# .agnaL zsaku�� si eman ym ,iH

# Output in Python 3
# Hi, my name is Łukasz Langa.
# .agnaL zsakuŁ si eman ym ,iH
# .agnaL zsakuŁ si eman ym ,iH