Python 2.x 字符编码问题

ASCII,Unicode,UTF-8 和 UTF-16

ASCII是一种我们最为熟悉的编码方式,从大一入学学C语言的时候就学过。那么到底什么是编码呢?我们知道数据实际上是以二进制的形式存储的,而我们人类可读的却是特定形式的字符(如’a’,’b’,’c’),而编码就是这样一种映射关系,它把每一个字符映射为一个二进制数,使得我们可以将数据存到内存或磁盘里。而 ASCII 码将英文字符映射为 8 比特二进制数,最多可以编码2**8-1=255 种不同字符。(ASCII 码
但是世界上有很多种语言,比如汉语这种拥有上万字符的语言,用 ASCII 来编码显然是不够的,所以许多国家就出台了自己的编码规约,我国的简体中文的编码方式是 GBK。但是每个国家所出台的字符的编码方式,并不能兼容,带来了不小的麻烦。
那么 Unicode 又是什么呢?实际上 Unicode 是一种编码方式,只是它将字符映射为 16 比特长的二进制码,希望借此将所有语言的编码统一起来。所以 Unicode 是一种将一个字符转换为 16 个比特的编码方式,最多可以表示 65535 个不同字符(实际上现在 Unicode 可以表示超过百万个字符,但这不是今天的重点)。
那么 UTF-8,UTF-16 和 Unicode 又是什么关系?以 UTF-8 为例,
UTF-8 全称是 UCS Transfer Format 8,UCS 传输格式,UTF-8表示每次传输 8 个比特。实际上 Unicode 只规定了序号和字符之间的映射关系,没有规定实际的编码方式。而 UTF-8 就是 Unicode 的一种编码实现,它是一种变长的编码,为保证对 ASCII 码的兼容,其编码方式如下,表中 x 的地方就是对应 Unicode 各二进制位的位置:

Unicode 十六进制 对应 UTF-8 编码二进制表示
0000 0000-0000 007F 0xxxxxxx
0000 0080-0000 07FF 110xxxxx 10xxxxxx
0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

例如 “我”这个汉字的 Unicode 为”+U6211”,对应二进制是
0110 001000 010001,因为常用汉字的 UTF-8 码都是三个字节长,所以它对应的的 UTF-8 码就是 1110(0110) 10(001000) 10(010001),对应的三个十六进制数就是 0xe6,0x88,0x91。

一些 Python 里的例子

>>> s = '我爱中国'
>>> s # 这是 s 的字节码
'\xe6\x88\x91\xe7\x88\xb1\xe4\xb8\xad\xe5\x9b\xbd'
>>> len(s)
12
>>> s1 = s.decode('utf-8') # 使用 UTF-8 进行解码
>>> s1 # 这是 s 的 Unicode 编码
u'\u6211\u7231\u4e2d\u56fd'
>>> len(s1)
4
>>> s2 = u'我爱中国'
>>> s2
u'\u6211\u7231\u4e2d\u56fd'
>>> assert s1 == s2

一些相关内容

str 和 unicode

这里写图片描述

在 Python 中,Unicode 是没有格式的,或者说 Unicode 本身就是没有格式的,只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储;它被用做字符串编码基准,即要么将 Unicode 编码成某一个字符串,要么某个字符串被解码为 Unicode。
而 str 在 Python 中是原始字节码,需要按照对应的编码方式进行解码才能还原原始信息。

decode 和 encode

s.decode(encoding): 把字符串按照给定的编码格式解码为 Unicode,返回值类型为 unicode

>>> s = '中国'
>>> s
'\xe4\xb8\xad\xe5\x9b\xbd'
>>> s.decode('utf-8')
u'\u4e2d\u56fd'

s.encode(encoding): 把 Unicode 按照给定的编码格式进行编码,
返回值类型为 str

>>> s = u'中国'
>>> s
u'\u4e2d\u56fd'
>>> s.encode('gbk')
'\xd6\xd0\xb9\xfa'

参考链接

python字符串编码及乱码解决方案
Python字符编码详解
字符编码笔记:ASCII,Unicode和UTF-8

猜你喜欢

转载自blog.csdn.net/preyta/article/details/70176526