Pyhotn 中编码的问题:'ascii' codec can't decode byte 0xef in position 0: ordinal not in range(128)的错误

在Django视图函数中经常出现类似于'ascii' codec can't decode byte 0xef in position 0:ordinal not in range(128)的错误。

        在解决错误之前,首先要了解unicode和utf-8的区别。

        unicode指的是万国码,是一种“字码表”。而utf-8是这种字码表储存的编码方法。unicode不一定要由utf-8这种方式编成bytecode储存,也可以使用utf-16,utf-7等其他方式。目前大多都以utf-8的方式来变成bytecode。

         其次,Python中字符串类型分为byte string 和 unicode string两种。

        如果在python文件中指定编码方式为utf-8(#coding=utf-8),那么所有带中文的字符串都会被认为是utf-8编码的byte string(例如:mystr="你好"),但是在函数中所产生的字符串则被认为是unicode string。
        问题就出在这边,unicode string 和 byte string 是不可以混合使用的,一旦混合使用了,就会产生这样的错误。例如:
        self.response.out.write("你好"+self.request.get("argu"))
        其中,"你好"被认为是byte string,而self.request.get("argu")的返回值被认为是unicode string。由于预设的解码器是ascii,所以就不能识别中文byte string。然后就报错了。

 


        以下有两个解决方法:
       1.将字符串全都转成byte string。
            self.response.out.write("你好"+self.request.get("argu").encode("utf-8"))
        2.将字符串全都转成unicode string。
           self.response.out.write(u"你好"+self.request.get("argu"))
            byte string转换成unicode string可以这样转unicode(unicodestring, "utf-8")

 

我的经验:

 

我是画图的时候,从数据框中取出的序列列名是中文的,序列不仅包括其中的数据,还有列名,于是整个的编码就是混合的,不是byte string(在开头规定了#coding = utf-8),画图时总是报 

'ascii' codec can'tdecode byte 0xef in position 0: ordinal not in range(128)

解决方式:

一般而言编码错误采用转码,unicode,encode等,但是这些操作是对于string而言,这里是序列,不便于操作,于是

(1)改变默认的编码方式

import sys

reload(sys)

sys.setdefaultencoding('utf-8')

问题可以得到解决,但是在notebook中不在显示Print后的内容,不太想用。

 

(2)将序列中的值取出来,不用序列画图,而是用多维数组画图

s.values

问题也可以解决。

(3)后来发现当DataFrame列名包含中文,还需要添加横轴坐标,不得不用到中文,此时整个列名显示好像是uicode编码

Index([u'全部', u'加赔'], dtype='object')

但是整个加入横轴坐标设置就是报错,编码不对,单个取出

'\xe5\x85\xa8\xe9\x83\xa8'

显然不是unicode(不知道为什么会这样??

用判断也表示不是uicode

isinstance(x_ticks1[0], unicode)

False


可以用str.decode('utf8')只能单个str用,序列没有这个功能,转为unicode,就对了。后来画图是可以显示中文了,不过还是很疑惑为什么?

==========================================================================================

Python字符串的编码与解码(encode与decode)

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

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

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

在某些IDE中,字符串的输出总是出现乱码,甚至错误,其实是由于IDE的结果输出控制台自身不能显示字符串的编码,而不是程序本身的问题。

例如:ljq.py,编码为utf8,包含内容如下:


#-*-coding:utf-8-*- 

s='中文'
print type(s) #查看s的字符类型
print s  

s.decode('utf8') #解码utf8,默认的编码方式是unicode
s.decode('gbk', "ignore") #解码utf8,忽略其中有异常的编码,仅显示有效的编码
s.decode('gbk', 'replace')
print type(s)
print s

s.encode('gb2312') ##编码为utf8
print type(s)
print s

ljq.py编码必需与s.decode('utf8')指定的编码一致,不然会抛出解码异常信息,可以通过s.decode("gbk", "ignore")或s.decode("gbk", "replace")来解决。

另外对于一些包含特殊字符的编码,直接解码可能会报错,可以使用对于的参数来设置。如:
s.decode("utf-8", "ignore") 忽略其中有异常的编码,仅显示有效的编码
s.decode("utf-8", "replace") 替换其中异常的编码,这个相对来可能一眼就知道那些字符编码出问题了。

从unicode转str,被看做是把一个信息文本编码为二进制字节流的过程,要用encode方法

======================================================================================

那么str.decode('utf8')是将utf8编码转为unicode? 好乱的感觉?不过这样可以正确显示,表示很无力?

难道只有unicode编码才能用encode??




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值