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)中的鏈接裏也提到了這一點,最開始沒有發現: