我确定有很多关于Unicode和Python的说明,但为了方便自己的理解使用,我还是打算再写一些关于它们的东西。
我们先来用Python定义一个字符串。当你使用string类型时,实际上会储存一个字节串。
12 | [ a ][ b ][ c ] = \”abc\”[ 97 ][ 98 ][ 99 ] = \”abc\” |
在这个例子里,abc这个字符串是一个字节串。97.,98,,99是ASCII码。Python 2.x版本的一个不足之处就是默认将所有的字符串当做ASCII来对待。不幸的是,ASCII在拉丁式字符集里是最不常见的标准。
ASCII是用前127个数字来做字符映射。像windows-1252和UTF-8这样的字符映射有相同的前127个字符。在你的字符串里每个字节的值低于127的时候是安全的混合字符串编码。然而作这个假设是件很危险的事情,下面还将会提到。
当你的字符串里有字节的值大于126的时候就会出现问题了。我们来看一个用windows-1252编码的字符串。Windows-1252里的字符映射是8位的字符映射,那么总共就会有256个字符。前127个跟ASCII是一样的,接下来的127个是由windows-1252定义的其他字符。
12 | A windows–1252 encoded string looks like this:[ 97 ] [ 98 ] [ 99 ] [ 150 ] = \”abc–\” |
Windows-1252仍然是一个字节串,但你有没有看到最后一个字节的值是大于126的。如果Python试着用默认的ASCII标准来解码这个字节流,它就会报错。我们来看当Python解码这个字符串的时候会发生什么:
1234567 | >>> x = \”abc\” + chr(150)>>> print repr(x)\’abc\\x96\’>>> u\”Hello\” + xTraceback (most recent call last): File \” |
我们来用UTF-8来编码另一个字符串:
123 | A UTF–8 encoded string looks like this:[ 97 ] [ 98 ] [ 99 ] [ 226 ] [ 128 ] [ 147 ] = \”abc–\”[0x61] [0x62] [0x63] [0xe2] [ 0x80] [ 0x93] = \”abc-\” |
如果你拿起看你熟悉的Unicode编码表,你会发现英文的破折号对应的Unicode编码点为8211(0x2013)。这个值大于ASCII最大值127。大于一个字节能够存储的值。因为8211(0x2013)是两个字节,UTF-8必须利用一些技巧告诉系统存储一个字符需要三个字节。我们再来看当Python准备用默认的ASCII来编码一个里面有字符的值大于126的UTF-8编码字符串。
1234567 | >>> x = \”abc\\xe2\\x80\\x93\”>>> print repr(x)\’abc\\xe2\\x80\\x93\’>>> u\”Hello\” + xTraceback (most recent call last): File \” |
你可以看到,Python一直是默认使用ASCII编码。当它处理第4个字符的时候,因为它的值为226大于126,所以Python抛出了错误。这就是混合编码所带来的问题。
在一开始学习Python Unicode 的时候,解码这个术语可能会让人很疑惑。你可以把字节流解码成一个Unicode对象,把一个Unicode 对象编码为字节流。
Python需要知道如何将字节流解码为Unicode对象。当你拿到一个字节流,你调用它的“解码方法来从它创建出一个Unicode对象。
你最好是尽早的将字节流解码为Unicode。
123456789 | >>> x = \”abc\\xe2\\x80\\x93\”>>> x = x.decode(\”utf-8\”)>>> print type(x)<type \’unicode\’>>>> y = \”abc\” + chr(150ack/trans-team/\”>翻译组。
我确定有很多关于Unicode和Python的说明,但为了方便自己的理解使用,我还是打算再写一些关于它们的东西。
字节流 vs Unicode对象我们先来用Python定义一个字符串。当你使用string类型时,实际上会储存一个字节串。
在这个例子里,abc这个字符串是一个字节串。97.,98,,99是ASCII码。Python 2.x版本的一个不足之处就是默认将所有的字符串当做ASCII来对待。不幸的是,ASCII在拉丁式字符集里是最不常见的标准。 ASCII是用前127个数字来做字符映射。像windows-1252和UTF-8这样的字符映射有相同的前127个字符。在你的字符串里每个字节的值低于127的时候是安全的混合字符串编码。然而作这个假设是件很危险的事情,下面还将会提到。 当你的字符串里有字节的值大于126的时候就会出现问题了。我们来看一个用windows-1252编码的字符串。Windows-1252里的字符映射是8位的字符映射,那么总共就会有256个字符。前127个跟ASCII是一样的,接下来的127个是由windows-1252定义的其他字符。
Windows-1252仍然是一个字节串,但你有没有看到最后一个字节的值是大于126的。如果Python试着用默认的ASCII标准来解码这个字节流,它就会报错。我们来看当Python解码这个字符串的时候会发生什么:
我们来用UTF-8来编码另一个字符串:
如果你拿起看你熟悉的Unicode编码表,你会发现英文的破折号对应的Unicode编码点为8211(0x2013)。这个值大于ASCII最大值127。大于一个字节能够存储的值。因为8211(0x2013)是两个字节,UTF-8必须利用一些技巧告诉系统存储一个字符需要三个字节。我们再来看当Python准备用默认的ASCII来编码一个里面有字符的值大于126的UTF-8编码字符串。
你可以看到,Python一直是默认使用ASCII编码。当它处理第4个字符的时候,因为它的值为226大于126,所以Python抛出了错误。这就是混合编码所带来的问题。
解码字节流在一开始学习Python Unicode 的时候,解码这个术语可能会让人很疑惑。你可以把字节流解码成一个Unicode对象,把一个Unicode 对象编码为字节流。 Python需要知道如何将字节流解码为Unicode对象。当你拿到一个字节流,你调用它的“解码方法来从它创建出一个Unicode对象。 你最好是尽早的将字节流解码为Unicode。
|