在Python中以人类可读的格式解码pickle文件

时间:2019-03-17 04:12:10

标签: python python-3.x

import pickle

data_pkl = open("data.pkl", "rb")
d_c = data_pkl.read()
data_pkl.close()
print(d_c)

我是处理数据结构的新手。当我尝试读取泡菜数据时,结果如下所示:

b'\ x80 \ x03} q \ x00(X \ x05 \ x00 \ x00 \ x00Phoneq \ x01} q \ x02(cnumpy.core.multiarray \ nscalar \ nq \ x03cnumpy \ ndtype \ nq \ x04X \ x02 \ x00 \ x00 \ x00i8q \ x05K \ x00K \ x01 \ x87q \ x06Rq \ x07(K \ x03X \ x01 \ x00 \ x00 \ x00

.........长行

如何在python中将其转换为人类可读的格式?

2 个答案:

答案 0 :(得分:1)

转储数据时,pickle产生一个字节字符串。这就是你所拥有的。

例如:

import pickle

data = {'text': 'value', 'list': [1, 2, 3]}

s = pickle.dumps(data)
print(s)

产生字节字符串:

b'\x80\x03}q\x00(X\x04\x00\x00\x00textq\x01X\x05\x00\x00'
b'\x00valueq\x02X\x04\x00\x00\x00listq\x03]q\x04(K\x01K'
b'\x02K\x03eu.'

note :为了便于阅读,我将长行分为3部分。

Python定义了几种协议,分别名为HIGHEST_PROTOCOLDEFAULT_PROTOCOL。因此,如果您更改协议,则可能会有不同的结果。

要读取此字节字符串,您需要使用pickle.load(或pickle.loads从字节字符串中读取)。

例如:

import pprint

obj = pickle.loads(s)
pprint.pprint(obj)

您得到:

{'list': [1, 2, 3], 'text': 'value'}

很酷,但是如果您的数据包含未知类型的实例,则将无法反序列化。

这里是一个例子:

import pickle
import pprint


class UnknownClass:
    def __init__(self, value):
        self.value = value


data = {'text': 'value',
        'list': [1, 2, 3],
        'u': UnknownClass(25)}

s = pickle.dumps(data)
print(s)

del UnknownClass

obj = pickle.loads(s)

此处的del语句用于模拟未知类型。

结果将是:

Traceback (most recent call last):
  File "/path/to/stack.py", line 19, in <module>
    obj = pickle.loads(s)
AttributeError: Can't get attribute 'UnknownClass' on <module '__main__' from '/path/to/stack.py'>

有关更多信息,请在Python文档中指定协议。

答案 1 :(得分:0)

我建议您阅读Python文档,尤其是pickle module docs。您当前的代码正在导入pickle,但实际上并没有使用pickle,因为您只是使用read()加载了文件。使用pickle.load()或其他pickle方法应该可以解决问题。

例如:

d_c = pickle.load(data_pkl)

编辑以添加来自文档的强制性腌制警告:

  

警告:泡菜模块无法防止错误或恶意破坏   构造的数据。切勿破坏从不受信任或   未经身份验证的来源。

(解开未知文件会使您容易在计算机上执行任意代码,因此请小心解开!)