最近颇受编码问题困扰,所以稍作总结,附以代码说明
-
为什么需要编解码?
字符串以unicode的形式存在于内存中 ,但是unicode只是规定如何编码,并没有规定如何保存、传输这个编码,也就是说unicode不能直接写入文件或者在网络上传输,所以得通过某种编码使unicode变成连续的字节(bytes),同样地,对读入的数据解码,以unicode形式存在于内存中.
举例来说,在写python时,python语言处理的字符串就是内存中的unicode,写入到文件时得把unicode用utf-8,GBK等方式编码成连续的字节;用python从文件读入数据时,得用utf-8,GBK等方式把连续的字节解码成unicode.使用的解码方式务必要和编码方式一致
-
python默认的编解码方式
可以通过下面两行代码 (示例1) 获得,一般默认是ascii,本示例中就是对unicode用ascii编码为字符串,ascii不能表示汉字,所以输入汉字时就会报错 (示例2)#示例1 import sys print sys.getdefaultencoding() #ascii #示例2 print "搁浅" #SyntaxError: Non-ASCII character
-
如何print汉字?
情况一: 在python中直接输入中文 (示例3)
得让python文件支持中文,将python文件的编码格式改为utf-8,就是我们通常看到的 # -*- coding:utf-8 -*-#示例3 # -*- coding:utf-8 -*- print "搁浅"
情况二: print指定编码的中文 (示例4)
示例4报错,因为在对"搁浅"encode之前,先需要把"搁浅"解码成unicode,之后再用utf-8编码,那么问题来了,怎么解码"搁浅" ? 获取python的默认编解码方式 (示例5),一般是ascii,所以会报错,将默认编解码方式设置成utf-8后就可以了 (示例6)#示例4 # -*- coding:utf-8 -*- a = "搁浅".encode("utf-8") #示例5 import sys print sys.getdefaultencoding() #示例6 import sys reload(sys) sys.setdefaultencoding("utf-8") print "搁浅".encode("utf-8")
-
python以十六进制显示非打印字符,"搁浅"这两个字的16进制编码分别是:69081,6B585
在python内部为:\xe6\x90\x81\xe6\xb5\x85 (示例7),其中,\x表示十六进制 ,e表示某个字符编码的开始#示例7 # -*- coding:utf-8 -*- #打印s在python内部的存在形式 s = ["搁浅"] print s
-
乱码
print出乱码极可能是因为编码与解码方式不统一 (示例8).utf-8编码,每个汉字用utf-8编码需要3个字节,用gbk编码需要2个字节. 用utf-8编码后解码,再用gbk编码,造成这样的问题:本该用3个字节表示的字符,强行用2个字节表示(示例9)#示例8 # -*- coding:utf-8 -*- s = ["搁浅"] print "搁浅".decode("utf-8").encode("gbk") #打印乱码:��dz #示例9 s = ["搁浅"] print s #输出:["\xe6\x90\x81\xe6\xb5\x85"] 每个汉字3个字节 s = ["搁浅".decode("utf-8").encode("gbk")] print s #输出:["\xb8\xe9\xc7\xb3"] 每个汉字2个字节
有待确认
python默认解码方式是ascii;
python源代码加上# -*- coding:utf-8 -*-后,不仅仅是源代码支持中文,而且print的默认编码方式也变成utf-8
推荐一个查看字符编码的网页,很好用,可以查看编码10进制, 编码16进制,Unicode编码10进制,Unicode编码16进制,python用的是 编码16进制
编码问题时不时出来阻挠一下,需要继续补充总结