为了账号安全,请及时绑定邮箱和手机立即绑定

用python 3解开python 2对象

用python 3解开python 2对象

慕姐8265434 2019-12-12 14:10:52
我想知道是否有一种方法可以加载使用Python 3.4和Python 2.4腌制的对象。我一直在大量公司遗留代码上运行2to3,以使其保持最新状态。完成此操作后,在运行文件时出现以下错误:  File "H:\fixers - 3.4\addressfixer - 3.4\trunk\lib\address\address_generic.py", line 382, in read_ref_files    d = pickle.load(open(mshelffile, 'rb'))UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 1: ordinalnot in range(128)在争用中查看腌制的对象,它dict在中dict,包含键和type的值str。所以我的问题是:有没有办法用python 3.4加载最初在python 2.4中腌制的对象?
查看完整描述

3 回答

?
犯罪嫌疑人X

TA贡献2080条经验 获得超4个赞

您必须告诉pickle.load()如何将Python字节字符串数据转换为Python 3字符串,或者可以告诉pickle将它们保留为字节。


默认设置是尝试将所有字符串数据解码为ASCII,并且解码失败。请参阅pickle.load()文档:


可选的关键字参数是fix_imports,encoding和errors,用于控制对Python 2生成的pickle流的兼容性支持。如果fix_imports为true,pickle将尝试将旧的Python 2名称映射到Python 3中使用的新名称。编码和错误告诉pickle如何解码Python 2腌制的8位字符串实例;它们分别默认为“ ASCII”和“ strict”。该编码可以是“字节”作为字节对象读取这些8位串的实例。


将编码设置为latin1可以直接导入数据:


with open(mshelffile, 'rb') as f:

    d = pickle.load(f, encoding='latin1') 

但是您需要验证是否没有使用错误的编解码器解码任何字符串;Latin-1适用于任何输入,因为它将字节值0-255直接映射到前256个Unicode代码点。


另一种选择是使用加载数据encoding='bytes',然后解码所有bytes键和值。


请注意,直到使用3.6.8、3.7.2和3.8.0之前的Python版本,除非使用,否则对Python 2 datetime对象数据的解泄漏都是无效的encoding='bytes'。




查看完整回答
反对 回复 2019-12-13
?
一只萌萌小番薯

TA贡献1795条经验 获得超7个赞

当您的对象中包含numpy数组时,使用encoding ='latin1'会引起一些问题。


使用编码=字节会更好。


请参阅此答案以获取有关使用encoding = bytes的完整说明


查看完整回答
反对 回复 2019-12-13
?
MMTTMM

TA贡献1869条经验 获得超4个赞

我意识到datetime评论不是此答案的主要目的,但对于未来的读者,我想指出的是,即使是“固定”版本的Python 3仍然需要encoding='latin-1'释放Python 2的日期时间。如果您腌制的Python 2数据恰好同时包含日期时间和以Latin-1以外的其他方式编码的字节串,那么encoding='bytes'毕竟还是会更好。


查看完整回答
反对 回复 2019-12-13
  • 3 回答
  • 0 关注
  • 349 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信