python2.7编码与解码

常见的编码
  ASCII: 美国人发明的,只编码英文字母和符号,1个字节。
  GB2312: 中国人发明的,增加了中文汉字和符号,2个字节。
  Unicode: 为了把所有语言都统一到一套编码里,一般是2个字节,生僻字4个字节。
  UTF-8: 为了节省英文字符内存空间,UTF-8可变长编码,常用的英文字母被编码成1个字节,汉字通常是3个字节,生僻的字符编码成4-6个字节。

 1 >>> S = '中文'
 2 >>> print type(S), len(S)
 3 <type 'str'> 4
 4 
 5 >>> unicodeS = u'中文'
 6 >>> print type(unicodeS), len(unicodeS)
 7 <type 'unicode'> 2
 8 
 9 >>> utfS = u'中文'.encode('utf-8')
10 >>> print type(utfS), len(utfS)
11 <type 'str'> 6


  在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码,这样可以节省很多存储空间。

   其中,python2和python3系统默认编码分别是ascii和utf-8,以python2.7为例:

 1 >>> import sys
 2 >>> sys.getdefaultencoding()
 3 'ascii'
 4 
 5 >>> a = 'hello'
 6 >>> print type(a)
 7 <type 'str'>
 8 >>> b = a.decode('ascii')
 9 >>> print type(b)
10 <type 'unicode'>
11 >>> c = a.decode('ascii').encode('utf-8')
12 >>> print type(c)
13 <type 'str'>

  然而python2.7中,比较麻烦的还是有两种数据模型来支持字符串这种数据类型,str和unicode(python3改进后只有unicode一种),比如s = '中文'就是str类型的字符串,而u=u"中文"就是一个unicode类型的字符串。unicode是由str类型的字符串解码后得到,unicode也可以编码成str类型。即

  str --> decode -->unicode
  unicode --> encode --> str

  在做编码转换时,通常需要以unicode作为中间编码,即先将其他编码的字符串解码(decode)成unicode,再从unicode编码(encode)成另一种编码。
  注:Unicode 格式:像\u0000;二进制编码 格式:像\x00\x00,其中utf-8,gbk就是二进制编码;

 1 >>> s1 = u'中文'
 2 >>> type(s1)
 3 <type 'unicode'>
 4 >>> s2 = 'ABC'
 5 >>> type(s2)
 6 <type 'str'>
 7 
 8 #字符串转码成unicode对象
 9 >>> u'ABC'
10 u'ABC'
11 >>> u'中文'
12 u'\u4e2d\u6587'
13 
14 #英文字符串编码成utf8格式
15 >>> 'ABC'.encode('utf-8')
16 'ABC'
17 >>> u'ABC'.encode('utf-8')
18 'ABC'
19 
20 #中文字符串需先转码成unicode,再编码成utf8格式
21 >>> '中文'.encode('utf-8')
22 
23 Traceback (most recent call last):
24   File "<pyshell#15>", line 1, in <module>
25     '中文'.encode('utf-8')
26 UnicodeDecodeError: 'utf8' codec can't decode byte 0xd6 in position 0: invalid continuation byte
27 
28 >>> u'中文'.encode('utf-8')
29 '\xe4\xb8\xad\xe6\x96\x87'
30 >>> u'\u4e2d\u6587'.encode('utf-8')
31 '\xe4\xb8\xad\xe6\x96\x87'
32 
33 #字符串从utf8格式解码成unicode
34 >>> 'ABC'.decode('utf-8')
35 u'ABC'
36 >>> '\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')
37 u'\u4e2d\u6587'
38 >>> print '\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')
39 中文

  编码检验和转换

 1 #检查编码
 2 >>> import urllib
 3 >>> rawdata = urllib.urlopen('http://www.google.cn/').read()
 4 >>> import chardet
 5 >>> chardet.detect(rawdata)
 6 {'confidence': 0.99, 'encoding': 'utf-8'}
 7 
 8 #将String对象从UTF-8内码转换为gbk,相反则s.decode('gbk').encode('utf-8')
 9 >>> rawdata.decode('utf-8').encode('gbk')
10 
11 #以unicode为中介实现编码或解码
12 >>> u'中文'.encode('gbk')
13 '\xd6\xd0\xce\xc4'
14 >>> u'中文'.encode('utf-8')
15 '\xe4\xb8\xad\xe6\x96\x87'
16 >>> '\xd6\xd0\xce\xc4'.decode('gbk')
17 u'\u4e2d\u6587'
18 >>> print u'\u4e2d\u6587'
19 中文
20 >>> '\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')
21 u'\u4e2d\u6587'
22 >>> print u'\u4e2d\u6587'
23 中文

其中,decode的函数原型是 decode([encoding], [errors='strict']),可以用第二个参数控制错误处理的策略。

   默认的参数就是strict,代表遇到非法字符时抛出异常;
     如果设置为ignore,则会忽略非法字符;
     如果设置为replace,则会用?取代非法字符;

 

 读写文件编码

  以test.txt文件为例,文件内容为“测试”。

 1 >>> #coding=utf-8
 2 >>> f = open("test.txt")
 3 >>> s = f.read()
 4 >>> print type(s)
 5 <type 'str'>
 6 >>> s
 7 '\xb2\xe2\xca\xd4'
 8 >>> u = s.decode("gbk")
 9 >>> u
10 u'\u6d4b\u8bd5'
11 >>> f.write(u.encode("utf-8"))
12 >>> print u
13 测试

 

posted on 2017-01-16 23:19  Ryana  阅读(643)  评论(0编辑  收藏  举报