1. 问题:UnicodeDecodeError: 'ascii' codec can't decode byte 0xf6 in position 0: ordinal not in range(128)
出错误的地方在 第101代码 return pickle.load(f)处,如下图所示:
# read aus
conds_filepath = os.path.join(self._root, self._opt.aus_file) #aus_openface.pkl文件的路径
self._conds = self._read_conds(conds_filepath) #读取pkl文件里面的内容
def _read_conds(self, file_path):
with open(file_path, 'rb') as f: #open函数打开一个文件,而f就是文件对象
return pickle.load(f) #f指文件对象,就是你从哪个文件load加载数据和把数据dump写入哪个文件
#补充知识:
#pickle.dump(obj, file, [,protocol]) 参数file表示obj要写入的文件对象,file必须以二进制可写模式打开,即“wb”
#pickle.load(file) 参数file必须以二进制可读模式打开,即“rb”
2. 出错原因:
我此处的代码:pickle.load,读取aus_openface.pkl文件的内容。文件aus_openface.pkl是我从别的地方下载的,不是我自己生成的,最终我发现别人的aus_openface.pkl文件生成时,是用latin1编码的。(当我自己生成aus_openface.pkl,再用pickle.load(f)加载aus_openface.pkl文件里的数据时,不会出现错误。)
3. 解决:
1)https://blog.csdn.net/farphone/article/details/85801266、https://www.cnblogs.com/CasonChan/p/4669799.html里面提到用:
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
但我试了这种方法,对我没用。
2)https://blog.csdn.net/qq_35892623/article/details/82941473 里提到设置默认编码格式:
#-*- coding : utf-8 -*-
# coding: utf-8
对我没用。
还提到加上encoding='gbk',对我也没用。
所以,我把我的代码with open(file_path, 'rb') as f:改成with open(file_path, 'rb',encoding="utf-8") as f:,还是没用。
4. 最终解决方法:
加上encoding='latin1', 代码改成如下所示,成功解决我的问题。
with open(file_path, 'rb') as f:
return pickle.load(f, encoding='latin1')
5. 解决问题的灵感:
因为看到了另一个项目里的一段代码,如下所示,代码里含有pickle.load(f, encoding='latin1') 。想到可能生成pkl文件编码的时候用的是latin1,所以pickle.load加载数据的时候也要用latin1,便在我的代码里加上encoding='latin1'试了一下,结果真的有用,成功解决问题。
def load_dict(self, pkl_path):
saved_dict = {}
with open(pkl_path, 'rb') as f:
saved_dict = pickle.load(f, encoding='latin1')
return saved_dict
最后也发现2的3)中的链接里也提到了这一点,最开始没有发现: