5分钟理解python乱码
python乱码的问题常见,只是临时解决而不系统理解的话,日后总会再找上来。
字符集编码简史
计算机是美帝发明的,最初只需要表示英文字母、标点符号,用单字节就够了,这时是ascii编码;后面其他国家用电脑表示不了自己的文字,又各自创建了各种编码,例如中文简体gbk;不同编码之间难沟通,有可能用中文Windows开发的软件在美国人电脑上就显示不了,所以最后发明了大一统的万国码,unicode。
unicode相当于英语,国际通用,用于国与国之间语言的转换交流。
编码种类
UTF-8是什么
使用unicode有时有点浪费空间。例如:利用unicode表示“Python”需要12个字节才能表示,比原来ASCII表示增加了1倍。
字符串在表示层时不会特别大(图像、音频更大),可以使用unicode来处理,但是存储层和传输层一般数据都会非常多,继续用unicode则浪费空间。
为了解决存储和网络传输的问题,出现了Unicode Transformation Format,学术名UTF,即:对unicode中的进行转换,以便于在存储和网络传输时可以节省空间。
乱码的根本原因
字符在不同的编码解码过程中,最终编码的格式与初始格式不同,就会乱码。不同操作系统、不同地区语言、不同阅读软件、不同编程语言的默认编码格式都不一定相同,要留意。
python2中的字符体系
python2发明的时候还没有unicode编码,也没想到会全球流行,它的默认编码是ascii的,要在第一行注释指定文件用utf-8编码才能使用中文。
# coding: utf-8
python2中有两种字符类型 str 和 unicode,可以用type(v)查看变量类型。
>>> a='好'>>> type(a)<type 'str'>>>> a'\xe5\xa5\xbd' >>> b=u'好'>>> type(b)<type 'unicode'>>>> bu'\u597d'
<type ‘unicode’>即是字符的unicode编码类型,<type ‘str’>则表示除unicode外的其他编码类型(UTF-8\GBK\Latin-1等)。
str与unicode的转换
decode时指定str原来的编码格式,encode指定要转换成的编码格式。
所以生成一个unicode类型变量有两种方式,一个是定义时以u开头,一个是对str类型进行decode
python3的改变
python3中将默认编码改为unicode,其他不兼容的地方也多,要区分。
简单用法
以py2为例, 牢记一点“表示层用unicode,存储传输用utf-8”
import sysreload(sys)sys.setdefaultencoding('utf-8')
oriCodeFormat = 'utf-8' # or 'gbk' 'latin-1' ...newVar = var.decode(oriCodeFormat)doSth(newVar)
参考
Python 编码为什么那么蛋疼? - Alex-金角大王的回答 - 知乎
Python 编码为什么那么蛋疼? - 刘志军的回答 - 知乎