python2字符编码问题总结

  • 各种编码转化由unicode对象中转,编码即是将unicode对象转换成各类编码字符串,解码即是将种类编码字符串转换成unicode对象
  • gbk编码与gb2312编码结果一致,gb2312只包括简体汉字,gbk(国标扩展)包括所有简体繁体汉字以及日文假名
  • 定义unicode对象
s = u"哈哈" #定义s为unicode对象,type unicode
s   #u'\u54c8\u54c8
print s #哈哈
  • 定义gbk字符串
s_gbk = "哈哈"  #定义为gbk字符串,type str
s_gbk   #'\xb9\xfe\xb9\xfe'
print s_gbk #哈哈
  • 定义utf-8字符串
s_utf8 = s.encode('utf-8')  #定义为utf-8字符串,type str
s_utf8  #'\xe5\x93\x88\xe5\x93\x88'
print s_utf8    #鍝堝搱

unicode对象与其他编码字符串互转

  • unicode对象转成其他编码字符串
s2gbk = s.encode('gbk') #定义为gbk字符串,type str
s2gbk   #'\xb9\xfe\xb9\xfe'
print s2gbk #哈哈
s2utf8 = s.encode('utf-8')  #定义为utf8字符串,type str
s2utf8  #'\xe5\x93\x88\xe5\x93\x88'
print s2utf8    #鍝堝搱
  • 其他编码字符串转成unicode对象
gbk2s = s_gbk.decode('gbk') #定义为unicode对象,type unicode
gbk2s   #u'\u54c8\u54c8
print gbk2s #哈哈
utf82s = s_utf8.decode('utf-8') #定义为unicode对象,type unicode
utf82s  #u'\u54c8\u54c8
print utf82s    #哈哈

其他编码字符串间互转

  • gbk编码字符串转成utf-8编码字符串
gbk2utf8 = s_gbk.decode('gbk').encode('utf-8')  #定义为utf字符串,type str
gbk2utf8    #'\xe5\x93\x88\xe5\x93\x88'
print gbk2utf8  #鍝堝搱
  • utf-8编码字符串转成gbk编码字符串
utf82gbk = s_utf8.decode('utf-8').encode('gbk') #定义为gbk字符串,type str
utf82gbk    #'\xb9\xfe\xb9\xfe'
print utf82gbk  #哈哈

其他编码字符串间直接互转(即未解码直接转码)

gbk2utf8 = s_gbk.encode('utf-8')    #可能会抛异常UnicodeDecodeError

如果抛出这个异常,原因在于gbk编码的字符串直接编码成utf-8编码的字符串时python会将其先解码成unicode再编码成utf-8,其中解码这一步使用的是默认编码。如果默认编码不是gbk就不能正常解码,所以会抛异常。
解决办法有二:

  • 手动解码后再编码,缺点在于程序中多处用到的话不方便修改
gbk2utf8 = s_gbk.decode('gbk').encode('utf-8')
  • 修改默认编码
import sys 
reload(sys) #reload的原因是python2.5后初始化后会删除下面那句
sys.setdefaultencoding('gbk')   #设置默认编码为gbk

print输出utf-8编码字符串乱码原因

print输出utf-8编码字符串原因,当print的为unicode对象时会直接处理输出,当print的为编码字符串时,会解码成unicode对象输出。默认的解码方式使用的是gb2312,而utf-8编码字符串不能用gb2312解码,所以输出乱码,可以手动解码后输出

print s_utf8.decode('utf-8')

文件编码声明与文件编码保存类型

  • 如果代码中出现了中文,想要正常显示的话建议在代码第一行或第二行添加语句
#-*- coding:utf-8 -*-

这个的作用是声明代码中将会出现中文,并且会将文件中的字符串使用此编码转换成unicode对象

  • 文件保存时选择的编码类型决定了文件中出现的中文将被保存成什么类型的编码字符串
    例如:
#-*- coding:utf-8 -*-
s = u'哈哈'

将此文件保存成utf-8编码。
首先获取’哈哈’的编码,由文件编码决定,为’\xe5\x93\x88\xe5\x93\x88’(哈哈的utf-8编码形式)
然后转成unicode对象,由编码声明决定,按utf-8解码成unicode对象

unicode对象存储的字符串与unicode对象互相转化

  • unicode对象转成其存储内容的字符串
s = u"哈哈" #定义s为unicode对象,type unicode,len=2
s   #u'\u54c8\u54c8
print s #哈哈

s_str = s.encode('unicode-escape')  #定义为str,type str,len=12
s_str   #'\\u54c8\\u54c8'   #多的两个\为转义
print s_str #\u54c8\u54c8
  • 存储unicode对象内容的字符串转成unicode对象
s_t = '\u54c8\u54c8'    #定义为str,type str,len=12
s_t #'\\u54c8\\u54c8'   #多的两个\为转义
print s_t   #\u54c8\u54c8

s_unicode = s_t.decode('unicode-escape')    #此时s_unicode与s完全一样,type unicode,len=2
s_unicode   #u'\u54c8\u54c8
print s_unicode #哈哈

发表评论