理解和解决Python2中的编码问题

前言

经常处理一些文本,处理英文语料没什么问题,但是到了中文这儿就让人抓狂了,稍微不注意就会窜出各种乱码错误,平时出现几个小错误试试调调也能过去,但是对于编码这个问题还是畏惧,这几天好好整理了一下python的编码问题,感谢万能的Google和万能的StackOverflow,算是解决了我当前对编码问题的一些困惑

编码的前世今生

从unicode说去

在计算机中,所有的东西都是以字节形式储存的,但是字节对于我们来说是没有具体意义的,因此我们需要把二进制字节转换成人们能够理解的字符。最早的是使用ASCII码将字符对应到二进制字节上,如下图
这里写图片描述
给定一个ASCII码65(十六进制41),我们知道它对应的是字符A,但是ASCII码仅仅能够表示有限的字符,于是ISO Latin1 或者8859-1,比ASCII码多拓展了96个字符,之后也有一些字符集进行了更多的拓展,但是世界范围内的字符是很多的,东亚的中日韩还有俄文等字符也需要对应的编码方式,这个时候Unicode的编码方式出来了,Unicode的想法是统一天下编码方式,Unicode涵盖了上数以千计的字符码点方法,而且Unicode留有还有很多未码点空间,所以Unicode能完全满足现在和之后若干年的人类编码需求。Unicode是一个以’U+’字符开头,后面跟着4位或者5位或者6位十六进制数字,下图展示了6种字符的Unicode码点方式:
这里写图片描述
那么接下来的问题就是如何把Unicode码点映射到二进制字节上,常用的码点映射方式有UTF-16、UTF-32,UTF-8。下图是UTF-8映射的一个实例:
这里写图片描述
可以看出,单字节的ASCII码字符仍然映射的是单字节,而且ASCII编码方式是UTF-8的子集。

理解python2的encode和decode

python的str和Unicode类型

python2的编码解码方式和python3不一样,这里暂且先表述python2 中的encode和decode。
在python2中,有两种不同的字符串数据类型,一种是 “str”对象,存储着字节,如果在字符串前使用一个’u’的前缀,表示的是这个字符的Unicode码点:

>>> my_string="Hello World"
>>> type(my_string)
<type 'str'>
>>> my_unicode=u"Hello World"
>>> type(my_unicode)
<type 'unicode'>

其中第一个是“str”另一个是“unicode”,这是不一样的,这点需要尤其注意,这两种都可以叫string,但是有时不一样的东西 这点会在之后介绍两者的区别。

python的encode和decode

首先明白一件事情,之前说过Unicode将所有的字符都对应上了相应的码点,而UTF-8或者ASCII码不过是对应从Unicode到字节的映射方式,既然有映射方式,那么就有映射方向。我们把从Unicode到字节码(byte string)称之为encode,把从字节码(byte string)到Unicode码称之为decode
看个小例子:

>>> s='中国'
>>> len(s)
6
>>> s.decode('utf-8')
u'\u4e2d\u56fd'
>>> s_decode=s.decode('utf-8')
>>> len(s_decode)
2
>>> s_decode.encode('utf-8')
'\xe4\xb8\xad\xe5\x9b\xbd'

这个例子中,s表示的是byte string,其长度有6个字节,将该byte string decode到s_decode,显然,s_decode是一个unicode字符串,其长度变成了2,也就是两个Unicode码点,然后我将s_decode这个Unicode string再次encode到byte string,可以看到这个字节的十六进制编码方式。

python2 的encode和decode errors解析

python2经常出现的错误就是,decode和encode的error问题,来具体看一下。
接着上面的例子:

>>> s_decode.encode(
  • 16
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值