解决Python2.7的UnicodeEncodeError: ‘ascii’ codec can’t encode异常错误

文件头声明编码

关于python文件头部分知识的讲解

顶部的:# -*- coding: utf-8 -*-或者# coding: utf-8目前有三个作用

  1. 如果代码中有中文注释,就需要此声明。
  2. 比较高级的编辑器(比如我的emacs),会根据头部声明,将此作为代码文件的格式。
  3. 程序会通过头部声明,解码初始化 u"人生苦短",这样的unicode对象,(所以头部声明和代码的存储格式要一致)。

Example1

 # -*- coding:utf-8 -*-
 su = "人生苦短" #su是一个utf-8格式的字节串
 u  = s.decode("utf-8") #  s被解码为unicode对象,赋给u
 sg = u.encode("gbk") # u被编码为gbk格式的字节串,赋给sg
 print sg

Note: 不能直接输出decode结果:u = s.decode("utf-8"); print u; 要encode后输出。

但是事实情况要比这个复杂,比如看如下代码:

1 s = "人生苦短"
2 s.encode('gbk')

看!str也能编码,(事实上unicode对象也能解码,但是意义不大)

Note:原理,当对str进行编码时,会先用默认编码将自己解码为unicode,然后在将unicode编码为你指定编码。

这就引出了python2.x中在处理中文时,大多数出现错误的原因所在:python的默认编码,defaultencoding是ascii

看这个例子:

1 # -*- coding: utf-8 -*-
2 s = "人生苦短"
3 s.encode('gbk')

上面的代码会报错,错误信息:UnicodeDecodeError: 'ascii' codec can't decode byte ......

因为你没有指定defaultencoding,所以它其实在做这样的事情:

1 # -*- coding: utf-8 -*-
2 s = "人生苦短"
3 s.decode('ascii').encode('gbk')

Example2

python2.x示例:

>>> ss = '北京市'  
>>> type(ss)  
<type 'str'>  
>>> us = ss.decode('gbk')  
>>> us  
u'\u5317\u4eac\u5e02'  
>>> type(us)  
<type 'unicode'>  
>>> nus = u'北京市'  
>>> nus  
u'\u5317\u4eac\u5e02'  
>>> ss  
'\xb1\xb1\xbe\xa9\xca\xd0'  
>>> gbks = nus.encode('gbk')  
>>> gbks  
'\xb1\xb1\xbe\xa9\xca\xd0'  
>>> print(gbks)  
北京市  
>>> utfs = nus.encode('utf-8')  
>>> utfs  
'\xe5\x8c\x97\xe4\xba\xac\xe5\xb8\x82'  
>>> print(utfs)  
鍖椾含甯  
>>> xx = utfs.decode('utf-8')  
>>> type(xx)  
<type 'unicode'>  

ss = '北京市' 采用终端默认的编码形式,windows命名行窗口默认是gbk编码,所以通过ss.decode('gbk')转化成unicode的序列。最后utf-8编码的utfs输出乱码也是因为cmd终端是gdk编码的。

该示例中可以看到“北京市”的三种编码序列:

unicode序列:u'\u5317\u4eac\u5e02'

gbk序列:'\xb1\xb1\xbe\xa9\xca\xd0'

utf-8序列:'\xe5\x8c\x97\xe4\xba\xac\xe5\xb8\x82'

python中设置默认编码defaultencoding

设置defaultencoding的代码如下:

1 reload(sys)
2 sys.setdefaultencoding('utf-8')

如果你在python中进行编码和解码的时候,不指定编码方式,那么python就会使用defaultencoding。

比如上一节例子中将str编码为另一种格式,就会使用defaultencoding。

s.encode("utf-8") 等价于 s.decode(defaultencoding).encode("utf-8")

Note: 这个过程是s先通过defaultencoding解码为unicode,再编码为utf-8类型的编码。

再比如你使用str创建unicode对象时,如果不说明这个str的编码格式,那么程序也会使用defaultencoding。

u = unicode("人生苦短") 等价于 u = unicode("人生苦短",defaultencoding)

代码中字符串的默认编码与代码文件本身的编码一致,但有时候不是,这样就会造成错误。

import sys
print sys.getdefaultencoding()
# 'ascii'

基本上是ascii编码方式(Python脚本文件是由utf-8编码的),由此Python自然调用ascii编码解码程序去处理字符流,当字符流不属于ascii范围内,就会抛出异常(ordinal not in range(128))。

指定文件字符集为utf-8

在文件头部加入以下代码:

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

注意:

字符串在Python内部的表示是unicode编码,因此,在做编码转换时,通常需要以unicode作为中间编码,即先将其他编码的字符串解码(decode)成unicode,再从unicode编码(encode)成另一种编码。

decode的作用是将其他编码的字符串转换成unicode编码,如str1.decode('gb2312'),表示将gb2312编码的字符串str1转换成unicode编码。

encode的作用是将unicode编码转换成其他编码的字符串,如str2.encode('gb2312'),表示将unicode编码的字符串str2转换成gb2312编码。

因此,转码的时候一定要先搞明白,字符串str是什么编码,然后decode成unicode,然后再encode成其他编码

代码中字符串的默认编码与代码文件本身的编码一致,为防止特殊情况最好加上上面三行代码。

如:s='中文'
如果是在utf8的文件中,该字符串就是utf8编码,如果是在gb2312的文件中,则其编码为gb2312。这种情况下,要进行编码转换,都需要先用decode方法将其转换成unicode编码,再使用encode方法将其转换成其他编码。通常,在没有指定特定的编码方式时,都是使用的系统默认编码创建的代码文件。

转载于:https://my.oschina.net/u/2000675/blog/880781

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值