使用 Python 3 解压 Python 2 对象
- 2025-02-27 09:07:00
- admin 原创
- 79
问题描述:
我想知道是否有办法用 Python 3.4 加载在 Python 2.4 中腌制的对象。
我一直在大量公司遗留代码上运行 2to3 以使其保持最新。
完成此操作后,运行文件时出现以下错误:
File "H:ixers - 3.4addressfixer - 3.4 runklibaddressaddress_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: ordinal
not in range(128)
查看争用中的 pickle 对象,它是dict
中的dict
,包含 类型的键和值str
。
所以我的问题是:有没有办法用 python 3.4 加载最初在 python 2.4 中腌制的对象?
解决方案 1:
您必须告诉pickle.load()
如何将 Python 字节串数据转换为 Python 3 字符串,或者您可以告诉pickle
它们保留为字节。
默认尝试将所有字符串数据解码为 ASCII,但解码失败。请参阅pickle.load()
文档:
可选的关键字参数是fix_imports、encoding和errors,它们用于控制对 Python 2 生成的 pickle 流的兼容性支持。如果fix_imports为真,pickle 将尝试将旧的 Python 2 名称映射到 Python 3 中使用的新名称。encoding 和 errors告诉pickle如何解码 Python 2 pickled 的 8 位字符串实例;它们分别默认为 'ASCII' 和 'strict'。encoding可以是 'bytes ',以便将这些 8 位字符串实例读取为字节对象。
设置编码latin1
允许您直接导入数据:
with open(mshelffile, 'rb') as f:
d = pickle.load(f, encoding='latin1')
但您需要验证您的字符串是否使用错误的编解码器进行解码;Latin-1 适用于任何输入,因为它将字节值 0-255 直接映射到前 256 个 Unicode 代码点。
另一种方法是用 加载数据encoding='bytes'
,然后解码所有bytes
键和值。
请注意,在 Python 3.6.8、3.7.2 和 3.8.0 之前的版本中,除非使用,否则Python 2 对象数据的解封datetime
会中断encoding='bytes'
。
解决方案 2:
encoding='latin1'
当你的对象包含 numpy 数组时,使用会导致一些问题。
使用encoding='bytes'
會更好。
请参阅此答案以获取使用的完整说明encoding='bytes'
扫码咨询,免费领取项目管理大礼包!