42

您能否详细解释一下 Python 中字节字符串和 Unicode 字符串之间的区别。我读过这个

字节码只是将源代码转换为字节数组

这是否意味着 Python 有自己的编码/编码格式?还是使用操作系统设置?我不明白。你能解释一下吗?谢谢!

4

2 回答 2

38

没有 python 不使用自己的编码。它将使用它有权访问和您指定的任何编码。a 中的一个字符str代表一个 unicode 字符。然而,为了表示超过 256 个字符,单独的 unicode 编码每个字符使用一个以上的字节来表示许多字符。bytearray对象使您可以访问底层字节。str对象具有encode接受表示编码的字符串并返回表示该编码中的字符串的对象的方法bytearraybytearray对象具有decode接受表示编码的字符串并返回将str解释bytearray为以给定编码编码的字符串的方法。这是一个例子。

>>> a = "αά".encode('utf-8')
>>> a
b'\xce\xb1\xce\xac'
>>> a.decode('utf-8')
'αά'

我们可以看到 UTF-8 使用四个字节,\xce、\xb1、\xce 和 \xac 来表示两个字符。在 Ignacio Vazquez-Abrams 提到的 Spolsky 文章之后,我会阅读Python Unicode Howto

于 2012-04-08T04:52:04.783 回答
33

这是一个仅适用于 Python 3 的简单解释的尝试。我希望来自外行,这将有助于为完全没有经验的人消除一些困惑。如果有任何技术上的不准确之处,请原谅我并随时指出。

假设您以通常的方式使用 Python 3 创建一个字符串:

stringobject = 'ant'

stringobject将是一个 unicode 字符串。

unicode 字符串由 unicode 字符组成。在stringobject上面,unicode 字符是单个字母,例如 a、n、t

每个 unicode 字符都分配有一个代码点,它可以表示为一系列十六进制数字(一个十六进制数字可以取 16 个值,范围从 0-9 和 AF)。例如,字母'a'等价于'\u0061',而 'ant' 等价于'\u0061\u006E\u0074'

所以你会发现,如果你输入,

stringobject = '\u0061\u006E\u0074'
stringobject

您还将获得输出'ant'

现在, unicode在一个称为encoding的过程中被转换为 bytes将字节转换为 unicode的逆过程称为解码

这是怎么做到的?由于每个十六进制数字可以取 16 个不同的值,因此可以体现为一个 4 位二进制序列(例如十六进制数字 0 可以二进制表示为 0000,十六进制数字 1 可以表示为 0001 等等)。如果一个 unicode 字符有一个由四个十六进制数字组成的代码点,则它需要一个 16 位二进制序列来对其进行编码。

不同的编码系统规定了将 unicode 转换为位的不同规则。最重要的是,编码用于表示每个 unicode 字符的位数不同。

例如,ASCII 编码系统每个字符仅使用 8 位(1 个字节)。因此,它只能对码点最长为两个十六进制数字的 unicode 字符进行编码(即 256 个不同的 unicode 字符)。UTF-8 编码系统每个字符使用 8 到 32 位(1 到 4 个字节),因此它可以对 unicode 字符进行编码,其代码点最长为 8 个十六进制数字,即一切。

运行以下代码:

byteobject = stringobject.encode('utf-8')
byteobject, type(byteobject)

使用 utf-8 编码系统将 unicode 字符串转换为字节字符串,并返回b'ant', bytes'.

请注意,如果您使用 'ASCII' 作为编码系统,则不会遇到任何问题,因为 'ant' 中的所有代码点都可以用 1 个字节表示。但是,如果你有一个 unicode 字符串,其中包含的字符的代码点长于两个十六进制数字,你会得到一个UnicodeEncodeError.

相似地,

stringobject = byteobject.decode('utf-8')
stringobject, type(stringobject)

给你'ant', str

于 2016-01-09T15:37:41.727 回答