5分钟理解python乱码

python乱码的问题常见,只是临时解决而不系统理解的话,日后总会再找上来。

字符集编码简史

计算机是美帝发明的,最初只需要表示英文字母、标点符号,用单字节就够了,这时是ascii编码;后面其他国家用电脑表示不了自己的文字,又各自创建了各种编码,例如中文简体gbk;不同编码之间难沟通,有可能用中文Windows开发的软件在美国人电脑上就显示不了,所以最后发明了大一统的万国码,unicode。

unicode相当于英语,国际通用,用于国与国之间语言的转换交流。

编码种类
  • ASCII 占1个字节,只支持英文
  • GB2312 占2个字节,支持6700+汉字
  • GBK GB2312的升级版,支持21000+汉字
  • Shift-JIS 日本字符
  • ks_c_5601-1987 韩国编码
  • TIS-620 泰国编码
  • unicode 2-4字节 直接支持全球所有语言,已经收录136690个字符,并还在一直不断扩张中
UTF-8是什么

使用unicode有时有点浪费空间。例如:利用unicode表示“Python”需要12个字节才能表示,比原来ASCII表示增加了1倍。

字符串在表示层时不会特别大(图像、音频更大),可以使用unicode来处理,但是存储层和传输层一般数据都会非常多,继续用unicode则浪费空间。

为了解决存储和网络传输的问题,出现了Unicode Transformation Format,学术名UTF,即:对unicode中的进行转换,以便于在存储和网络传输时可以节省空间。

  • UTF-8: 使用1、2、3、4个字节表示所有字符;优先使用1个字符、无法满足则使增加一个字节,最多4个字节。英文占1个字节、欧洲语系占2个、东亚占3个,其它及特殊字符占4个
  • UTF-16: 使用2、4个字节表示所有字符;优先使用2个字节,否则使用4个字节表示。
  • UTF-32: 使用4个字节表示所有字符;总结: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'>
>>> b
u'\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”

  • 第一行指定源码文件的编码格式 #coding: utf-8
  • 重置进程的默认编码为utf-8
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
  • 使用时将字符变量都decode为unicode
oriCodeFormat = 'utf-8' # or 'gbk' 'latin-1' ...
newVar = var.decode(oriCodeFormat)
doSth(newVar)

参考

Python 编码为什么那么蛋疼? - Alex-金角大王的回答 - 知乎
Python 编码为什么那么蛋疼? - 刘志军的回答 - 知乎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值