我正在尝试对从“已解析” .csv文件构造的.pkl文件使用cPickle。使用预先构建的python工具箱进行解析,该工具箱最近已从python 2(https://github.com/GEMScienceTools/gmpe-smtk)移植到python 3。
我正在使用的代码如下:
from smtk.parsers.esm_flatfile_parser import ESMFlatfileParser
parser=ESMFlatfileParser.autobuild("Database10","Metadata10","C:/Python37/TestX10","C:/Python37/NorthSea_Inc_SA.csv")
import cPickle
sm_database = cPickle.load(open("C:/Python37/TestX10/metadatafile.pkl","r"))
它返回以下错误:
UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 44: character maps to <undefined>
根据我的收集,我需要指定.pkl文件的编码以使cPickle正常工作,但是我不知道通过解析.csv文件生成的文件上的编码是什么,所以我可以目前不使用cPickle。
我使用sublime文本软件发现它是“十六进制”,但是这不是Python 3.7中接受的编码格式,不是吗?
如果有人知道如何确定所需的编码格式,或者如何使十六进制编码在Python 3.7中可用,他们的帮助将不胜感激。
P.s。使用的模块(例如“ ESMFlatfileparser”)是预先构建的工具箱的一部分。考虑到这一点,我是否还可能需要在此模块内以某种方式更改编码?
答案 0 :(得分:1)
代码正在以 text 模式('r'
)打开文件,但它应该是 binary 模式('rb'
)。
从documentation到pickle.load
(重点是我):
[The]文件可以是已打开以进行二进制读取的磁盘文件,io.BytesIO对象或符合此接口的任何其他自定义对象。
由于文件是以二进制模式打开的,因此无需为open
提供编码参数。可能需要为pickle.load
提供编码参数。来自同一文档:
可选的关键字参数是fix_imports,编码和错误,用于控制对Python 2生成的pickle流的兼容性支持。如果fix_imports为true,pickle将尝试将旧的Python 2名称映射到Python中使用的新名称。 3.编码和错误告诉pickle如何解码Python 2腌制的8位字符串实例;它们分别默认为“ ASCII”和“ strict”。编码可以是“字节”,以将这些8位字符串实例读取为bytes对象。要解开NumPy数组和Python 2腌制的日期时间,日期和时间实例,需要使用encoding ='latin1'。
这应该防止UnicodeDecodeError
:
sm_database = cPickle.load(open("C:/Python37/TestX10/metadatafile.pkl","rb"))