Python2.7编解码问题总结

最近颇受编码问题困扰,所以稍作总结,附以代码说明

  1. 为什么需要编解码?
    字符串以unicode的形式存在于内存中 ,但是unicode只是规定如何编码,并没有规定如何保存、传输这个编码,也就是说unicode不能直接写入文件或者在网络上传输,所以得通过某种编码使unicode变成连续的字节(bytes),同样地,对读入的数据解码,以unicode形式存在于内存中.
    举例来说,在写python时,python语言处理的字符串就是内存中的unicode,写入到文件时得把unicode用utf-8,GBK等方式编码成连续的字节;用python从文件读入数据时,得用utf-8,GBK等方式把连续的字节解码成unicode.使用的解码方式务必要和编码方式一致

  2. python默认的编解码方式
    可以通过下面两行代码 (示例1) 获得,一般默认是ascii,本示例中就是对unicode用ascii编码为字符串,ascii不能表示汉字,所以输入汉字时就会报错 (示例2)

    1
    2
    3
    4
    5
    6
    7
    8
    #示例1
    import sys
    print sys.getdefaultencoding()
    #ascii

    #示例2
    print "搁浅"
    #SyntaxError: Non-ASCII character
  3. 如何print汉字?
    情况一: 在python中直接输入中文 (示例3)
    得让python文件支持中文,将python文件的编码格式改为utf-8,就是我们通常看到的 # -*- coding:utf-8 -*-

    1
    2
    3
    #示例3
    # -*- coding:utf-8 -*-
    print "搁浅"

    情况二: print指定编码的中文 (示例4)
    示例4报错,因为在对”搁浅”encode之前,先需要把”搁浅”解码成unicode,之后再用utf-8编码,那么问题来了,怎么解码”搁浅” ? 获取python的默认编解码方式 (示例5),一般是ascii,所以会报错,将默认编解码方式设置成utf-8后就可以了 (示例6)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #示例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")
  4. python以十六进制显示非打印字符,”搁浅”这两个字的16进制编码分别是:69081,6B585
    在python内部为:\xe6\x90\x81\xe6\xb5\x85 (示例7),其中,\x表示十六进制 ,e表示某个字符编码的开始

    1
    2
    3
    4
    5
    #示例7
    # -*- coding:utf-8 -*-
    #打印s在python内部的存在形式
    s = ["搁浅"]
    print s
  5. 乱码
    print出乱码极可能是因为编码与解码方式不统一 (示例8).utf-8编码,每个汉字用utf-8编码需要3个字节,用gbk编码需要2个字节. 用utf-8编码后解码,再用gbk编码,造成这样的问题:本该用3个字节表示的字符,强行用2个字节表示(示例9)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #示例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个字节
  6. 有待确认
    python默认解码方式是ascii;
    python源代码加上# -*- coding:utf-8 -*-后,不仅仅是源代码支持中文,而且print的默认编码方式也变成utf-8

推荐一个查看字符编码的网页,很好用,可以查看编码10进制, 编码16进制,Unicode编码10进制,Unicode编码16进制,python用的是 编码16进制

编码问题时不时出来阻挠一下,需要继续补充总结

0%