Python2.7 编码解码问题全面总结与应用实例

由于工作集群中部署的是Python2.7版本,缺乏python3的应用环境,因此将Python2.7中的编解码问题总结如下。

1. ASCII 、GB2312、Unicode 、UTF-8的关系:

1.1 ASCII(编码方式):

计算机在程序执行时只能识别二进制数,早期为了能够表示英文字符ABCD等,美国发明了ASCII码的编码方式。ASCII码将128个常用字符与8位二进制数一一对应,例如空格的ASCII码是32(二进制00100000),字母A是65等;由于编码128个字符只需占用7位二进制数(2^7=128), 因此ASCII码的8位数中的最高位统一规定为0。

1.2 GB2312(编码方式):中文汉字字符众多,一个字节只能表示256个符号,因此开发出GB2312采用2个字节表示一个汉字,因此理论可以表示出256^2=65536个符号,实际收录6763个

1.3 GBK(编码方式): 采用双字节表示,收录21886个汉字和多个图像符号,向下兼容GB2312。

1.4 Unicode(字符集、编码标准):Unicode不是编码方式, 是统一了全世界符号的字符集合,采用2个字节(十六进制数)规定了每个符号的二进制码,计算机内存中统一使用Unicode编码,但由于编码位数众多,极大浪费了存储空间,因此在存储或传输数据时会利用UTF-8等编码方式对unicode进行转换。

1.5 utf-8 (编码方式):是互联网使用最广的Unicode的实现方式,utf-8是变长的,使用1~4个字节,一个字符的utf-8编码若首位为0,则只包含一个字节,若首位为1,连续1的个数即为该字符占用的字节数

 

2 字符在计算机中的编码方式

2.1 终端显示字符的编码方式

windows下的终端是cmd,中文版windows默认为gbk编码,向下兼容gb2312;

linux下的终端是terminal,多数发行版linux的默认utf8编码,如zh_CN.utf8和en_US.utf8都是utf8编码,字符量相当。(zh_CN.utf8和en_US.utf8主要是语言环境上的区别,如时间、菜单、界面语言的显示等。)

2.2 文本文件的编码

文本文件的编码方式取决于编辑器,例如可以在py文本开头位置指定编码格式:#coding:utf-8

2.3 应用程序的内部编码

java和python的内部字符编码是utf-16,两者都支持用不同的编码方式对字节(byte)进行解码得到字符。

 

3 字符与字节的关系

计算机内部信息采用二进制存储,8个二进制位bit组合出一个字节,能表示2^8=256种状态;字节通过解码decode得到字符;字符通过编码encode得到字节,编解码的转换如下图所示。

 

 

4 #coding:utf-8 和 #-*-coding:utf-8-*- 的区别

在python2.7指定编码方式时,#coding:utf-8 和 #-*-coding:utf-8-*- 没有实质区别,事实上包含coding:utf-8或coding=utf-8的字符串均可识别,甚至是 #xxxxcoding:utf8 xxxx 也可以,但记得utf8后要接空格后再接其他字符。

 

5 #encoding:utf-8 和 sys.setdefaultencoding('utf-8')的区别

5.1 #encoding:utf-8

#用于告诉Python解释器该py文件用utf-8编码,指定后可用于解析代码中出现的中文,例如中文注释等;若不指定编码方式,则解释器默认使用ascii编码。

5.2 sys.setdefaultencoding('utf-8')

#用于指定在编解码时使用的默认方式,调用代码为:

import sys

reload(sys) #重新加载是因为首次加载时删除了sys中的setdefaultencoding(可能出于安全考虑)

sys.setdefaultencoding('utf-8') #指定在编码和解码时使用的默认方式

代码中对sys进行重新加载是由于首次加载时解释器删除了sys中的setdefaultencoding()方法(可能出于安全考虑),若不重加载则会因找不到setdefaultencoding()方法而报错。 

 

6 编码解码在python2.7的应用实例

6.1 在linux终端下,使用unicode('汉字','gb2312')报错,这是由于字符串'汉字'在linux下默认为utf-8编码,因此无法通过gb2312转换为Unicode,正确使用应为unicode('汉字','utf-8');同理在windows中使用unicode('汉字','utf-8')会报错,应该使用unicode('汉字','gb2312')。

6.2 在linux终端下,'汉字'.decode('gbk')不会报错,这是由于省略了采用默认方式utf-8进行编码的过程,程序会先通过utf-8转换为unicode,再用gbk进行解码。(如果是在py文件中,则要先对默认编码方式进行指定:import sys; reload(sys); sys.setdefaultencoding('utf-8'))。

6.3 打印字符时,若字符的编码方式与shell不一致会出现乱码,而在打印unicode的时候shell会自动对其解码,这时就不会乱码。

6.4 如何输出含有中文的list:print(','.join(data))

6.5 如何输出含有中文的以tuple为元素的list,例如[('卧槽','sad'),('sd','算法')]:','.join(map(lambda x: ','.join(x),a))

参考资料:

http://www.pulpcode.cn/2014/12/23/python-encode/   python中的str与unicode处理方法

https://www.cnblogs.com/liaohuiqiang/p/7247393.html     python2.7中的字符编码问题

https://www.zhihu.com/question/28164512?sort-created   知乎Kenneth的回答

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值