python2.X 中文编码问题

    鉴于github上很多深度学习代码都是用Python2.X写的,直接用Python3.X 可能因为软件包依赖问题导致很多bug,改的头晕眼花。但是Python2.X 因为Unicode和str内部编码问题,导致一遇到中文字符就会报这种错误(python3.x完美的解决了这个问题嘻嘻嘻,Python3.X大法好)。根据这几天改bug踩到的坑,总结一下。以供他日再次遇到只需!


在用python2.X处理中文最常见的两种错误信息如下:

错误1:

错误2:

      之所以出现这种错误是因为Python2.X 有两种字符串类型,1)str 对象,存储为字节形式,由Unicode经过编码构成  2)unicode,即在一个字符串前边加 u' '前缀,表示为这个字符的Unicode编码存储。 

     在这里首先简单区分一下计算机中的字符编码,详细知识可自行Google/baidu。熟悉计算机的人都知道在计算机中所有字符(数字 字符 符号等)都是以字节的形式存储的,但是人是无法读懂01串的,因此就有了01串到人类能够理解的字符串映射,比如最早的Ascii编码,如给定一个ascii 码65(0100 0001)根据表的映射关系我们知道他的意思是A。但是ASCII编码能表示的字符有限,后来为了能够有一个包括世界上所有已知字符的编码,提出了Unicode字符编码。自然就有一个问题,就是如何把Unicode映射到01串上,常见的映射方式有utf-8、utf-16、utf-32。其中单字节的ASCII码的编码方式是utf-8的子集。

     因此到此处,我们应该有个概念:Unicode将所有人类的字符都对应上了相应的码点。而utf-8和ascii就是从对应的Unicode码点到人类可理解的字符的映射方式,称这个过程为encode,即从Unicode到字节码(byte string)。反之称为decode,即从字节码(byte string)到Unicode码。

举个例子加深理解:


>>> s='你好'
>>>s
'\xe4\xbd\xa0\xe5\xa5\xbd'
>>> len(s)
6
>>> s.decode('utf-8')
u'\u4f60\u597d'

>>> a=s.decode('utf-8')
>>> len(a)
2

>>> a.encode('utf-8')
'\xe4\xbd\xa0\xe5\xa5\xbd'


s表示的是byte string,可以看到共有6个字节,所以长度为6。然后s, decode为a,即Unicode字符串,长度变为2,从输出可以看到为两个Unicode码点。然后a再次encode为byte string,长度变为6。

 


所以常见的错误就是encode 和decode过程中出现的错误了。重新回到原来问题。

对于错误1:

出现这种错误最常见的一个原因就是Python2默认以ascii方式解码,而中文没有对应的ascii编码,所以导致出错。正确做法如下

指定decode方式,而非默认的解码方式

总结:在python2.X 中,type为str类型的存储或者操作,一定要首先判断字符类型,如果为str,一定要指定decode('utf-8')才能与Unicode相互操作。

有没有更好地操作呢,网上最多的就是直接在文件开始的地方添加如下语句:

>>>import sys
>>>reload(sys)
<module 'sys' (built-in)>
>>>sys.setdefaultencoding('utf-8')

 

对于错误2:

一般为Unicode码点的字符 如前面的 b.encode('ascii'),因为ascii无法解码Unicode,所以会报错误2。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值