Python:klepto加载pickle图片字节文件返回None及原pickle解码错误求助
一、修复Pickle的UnicodeDecodeError错误
你遇到的这个错误,核心原因是用文本模式打开了包含二进制数据的pickle文件。图片字节属于二进制数据,而pickle在加载时如果文件以文本模式打开,会默认用ASCII编码去解码二进制字节,自然会触发解码失败的报错。
解决方法非常直接:打开文件时指定二进制只读模式rb,而非默认的文本模式r。修改你的pickle加载代码如下:
import pickle # 错误的打开方式(文本模式,会触发解码错误) # with open("your_file.pkl", "r") as file: # data = pickle.load(file) # 正确的打开方式(二进制模式,直接读取原始字节流) with open("your_file.pkl", "rb") as file: data = pickle.load(file)
这样就能正常加载包含图片字节的pickle数据了。
二、解决Klepto加载返回None的问题
从你的代码和输出来看,klepto返回None大概率是路径解析异常或者键名与文件名不匹配导致的,我们一步步排查解决:
修复路径转义问题
你写的路径'E:\localdb'中,\l会被Python当作转义字符处理(即便\l不是有效转义,也可能导致路径解析出错)。建议用两种方式修正路径:# 方法1:使用原始字符串,避免转义 localdb = dir_archive(r'E:\localdb', {}, serialized=True, cached=True) # 方法2:用双反斜杠代替单斜杠 localdb = dir_archive('E:\\localdb', {}, serialized=True, cached=True)确认键名与文件名的对应关系
dir_archive的load方法接收的是存储时用的键名,而非直接的文件名。如果你的output.pkl是之前用klepto生成的文件,那加载时应该用存储该数据的key(比如你存的时候用localdb['construction_imgs'] = data,加载时就用localdb.load('construction_imgs'))。要是你想把已有的pickle文件导入klepto,需要先手动读取pickle数据,再存入klepto:
import pickle from klepto.archives import dir_archive # 先读取本地pickle文件 with open(r'E:\localdb\K_Select all images with a construction vehicle\output.pkl', 'rb') as f: img_data = pickle.load(f) # 初始化klepto并存储数据 localdb = dir_archive(r'E:\localdb', {}, serialized=True, cached=True) localdb['construction_imgs'] = img_data localdb.dump() # 将数据保存到磁盘 # 后续加载数据 loaded_data = localdb.load('construction_imgs') print(loaded_data)验证文件路径的正确性
确保output.pkl确实存在于E:\localdb\K_Select all images with a construction vehicle\路径下,路径中的空格和特殊字符不会影响,但要保证拼写完全一致。
总结一下,优先尝试修复pickle的文件打开模式,这是解决原始问题最直接的方案;如果一定要用klepto,重点排查路径转义和键名匹配的问题即可。
内容的提问来源于stack exchange,提问作者Stefano Pozzi

