python 中 pickle 读档问题的解决方法

前言

要读取 .pkl 档,结果遇到各种状况,在网路上查了许多资料後终於解决了!
在这边简单做个过程纪录~
(如果想直接跳结果的话,可以 ctrl+F,搜寻:gzip.open() XD)

2021.01.21 更新 pickle.loads(f.read()) 方法

过程

一开始其实是先用了 pandas 中的 pd.read_pickle 来读取
结果报错了,也没查到什麽有效的解决方法

pd.read_pickle(filepath)

UnpicklingError: invalid load key, '\x1f'.

既然条条大路通罗马!那就试试别的方法吧~
所以後面就改成尝试用 pickle 中的 pickle.load 来读取,程序码如下:

print(os.path.isfile(filepath))
with open(filepath) as f:
    data = pickle.load(f)

结果这边第一个问题就出现了

UnicodeDecodeError: 'cp950' codec can't decode byte 0x8b in position 1: illegal multibyte sequence

看来是编码上的问题呀!
所以後来在 open 里面设定 encoding 的方式 [1]
这边尝试了各种编码方式,包括 UTF-8cp950big5hkscsISO-8859-1
在网路上查到有人也是在解决读档问题 [2],试了 gbkgb1830,不过他读取的是 .txt 档,但也顺便参考了他的方法,增加了这一条 errors='ignore'

with open(filepath, encoding='UTF-8', errors='ignore') as f:
    data = pickle.load(f)

不过用不同 encoding 报的错大同小异

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte

增加 errors='ignore' 後,又跑出另一个错

TypeError: a bytes-like object is required, not 'str'

虽然没有去深究这个错和增加上面那条的关系,不过这边到是给了个 bytes-like object 的线索![3]
所以在读取时多设定了 rb
意思是:read binary(rrbwwb之间的差异可以参考 [4]
而直接加上 rb 後又依序报这两个错,所以後来就只留下 rb

with open(filepath, 'rb', encoding='UTF-8', errors='ignore') as f:
    data = pickle.load(f)

ValueError: binary mode doesn't take an encoding argument
ValueError: binary mode doesn't take an errors argument

结果..... 怎麽回到了最一开始用 pd.read_pickle 时就出现的错误啊 @@

with open(filepath, 'rb') as f:
    data = pickle.load(f)
    
UnpicklingError: invalid load key, '\x1f'.

所以绕了一大圈,结果还是要回头解决原本的问题(人森啊....该面对的还是得面对 XD)

後来看到有人在解 pickle 压缩档(.gpkl)的时候,用了 gzip 的方法 [5]
开启档案时,改成用 gzip.open()

import gzip

with gzip.open(filepath, 'rb') as f:
    data = pickle.load(f)

结果成功了!!!


2021.01.21 更新
後来用上述方法要读取 .pickle 档案的时候,报了这个错:

OSError: Not a gzipped file (b'\x80\x04')

试了[6]的方法,当中的「解决方法2」在我的情况是可行的:pickle.loads(f.read())

with open(filepath, 'rb') as f:  
    data = pickle.loads(f.read())

後记

过程中感觉其实还有满多有趣的地方可以探讨,不过就先记录下来,留待之後有机会的时候再去研究~

如果有任何问题欢迎留言讨论,文中错误的地方还请不吝指正,谢谢!

References

[1] 解决 Python 中 UnicodeDecodeError: 'cp950' codec can't decode
[2] python读取中编码错误(illegal multibyte sequence)
[3] Pickle: TypeError: a bytes-like object is required, not 'str' [duplicate]
[4] python打开文件时'w'与'wb'的区别,'r'与'rb'的区别
[5] What causes the error “_pickle.UnpicklingError: invalid load key, ' '.”?
[6] TypeError: file must have 'read' and 'readline' attributes或者UnicodeDecodeError:


<<:  Vue ⑅:要开始Vue之前要先做的事

>>:  为什麽CISSP在台湾不被重视?

Day23-按钮分身术(上)_纯CSS汉堡图样与改变

今天明天要来写纯CSS可控制的按钮分身术 感谢室友的idea提供~ 之前在重写网站时的首页按钮也是类...

Day14 跟着官方文件学习Laravel-实作API(ㄧ)

昨天介绍了什麽是API及RESTful,今天要API对User进行CRUD,我们就利用laravel...

Angular 深入浅出三十天:表单与测试 Day23 - Reactive Forms 进阶技巧 - 栏位连动检核逻辑

大家在日常生活中,应该看过满多表单的某个栏位会随着另个栏位的改变,而造成该栏位的验证逻辑需要改变的...

【第五天 - Fluter BottomNavigationBar(下)行为分析】

前言 今日的程序码 => GITHUB 我们在开发的时候常常会遇到几种情况 需要 Bottom...

[第十四天]从0开始的UnityAR手机游戏开发-如何在辨识图卡时拨放影片03

在Project新增Create→C# Script取名为TrackableEvent 撰写程序码 ...