UnicodeDecodeError: 'ascii' codec can't decode byte 0xbb in position 5: ordinal not in range(128)

今天出现了这个问题,初步判断是编码问题

一般来说出现这个问题是代码里面有汉字,解决方法是:

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

但是如果采用上述方式的话,会在reload这里报错。

另外,我的代码里根本就没有汉字。

 

一步一步debug,在这一步出错

magic_number = pickle_module.load(f,**pickle_load_args)

 

  • 首先,了解python编码方式

【python2】中,我们使用decode()和encode()来进行解码和编码

字符串编码常用类型:utf-8,gb2312,cp936,gbk等。

在【python2】中,使用unicode类型作为编码的基础类型。即

       decode                     encode

str ---------> unicode --------->str

新版本的【python3】中,取消了unicode类型,代替它的是使用unicode字符的字符串类型(str),字符串类型(str)成为基础类型如下所示,而编码后的变为了字节类型(bytes)但是两个函数的使用方法不变:

        decode                    encode

bytes ------> str(unicode)------>bytes

 

  • f是.pkl文件,即数据集文件,print一下,发现是b'\xd0\x91'之类。

【u' blabla'】python3中,字符串的存储方式都是以Unicode字符来存储的,前缀带不带u其实都一样

【b'\xd0\x91'】bytes字符串的组成形式,必须是十六进制数,或者ASCII字符

Encoding from unicode to str.

>>> u"a".encode("utf-8")
'a'
>>> u"\u0411".encode("utf-8")
'\xd0\x91'
>>> "a".encode("utf-8")         # Unexpected argument type.
'a'
>>> "\xd0\x91".encode("utf-8")  # Unexpected argument type.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 0: ordinal not in range(128)

代码出处:https://wiki.python.org/moin/UnicodeDecodeError

  • 我的错误特别类似以上

you are reading UTF-8-encoded data, so you have to decodethe UTF-8-encoded String into a unicode string.

So just replace .encode  with  .decode , and it should work

 If your input data is not UTF-8 encoded, then you have to .decode() with the appropriate encoding, of course. If nothing is given, python assumes ASCII, which obviously fails on non-ASCII-characters.

所以我去查看数据类型了,发现pickle.load函数的一些设定:

pickle.loads(bytes_object, *, fix_imports=True, encoding="ASCII", errors="strict")

说明文档says:“可选的关键字参数是fix_imports,编码和错误,用于控制对Python 2生成的pickle流的兼容性支持。如果fix_imports为true,pickle将尝试将旧的Python 2名称映射到Python 3中使用的新名称。 编码和错误告诉pickle如何解码Python 2 pickle的8位字符串实例; 它们分别默认为“ ASCII”和“ strict”。 编码可以是“字节”,以将这些8位字符串实例读取为bytes对象。 要解开NumPy数组和Python 2pickle的日期时间,日期和时间实例,需要使用encoding ='latin1'。“

我看了一下我的函数,果然默认了encoding = ‘ascii’,我加了这么几行在出错行之前。emm竟然解决了。

for line in f:
    print(line)
print(type(MAGIC_NUMBER))

很玄学,只知道编码出现了问题,python遇到特殊的情况它无法编了就给我报的错。为什么好了我也不知道。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值