首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在python中给定了一个pickle转储,我如何确定所使用的协议?

在python中给定了一个pickle转储,我如何确定所使用的协议?
EN

Stack Overflow用户
提问于 2013-11-06 17:05:21
回答 2查看 2.2K关注 0票数 7

假设我有一个pickle转储文件或字符串,我如何确定用于自动创建pickle转储的协议?

如果是这样的话,我是否需要读取整个转储来确定协议,或者这可以在O(1)中实现?通过O(1),我想到了一些位于pickle字符串或文件开头的头信息,这些信息的读出不需要处理整个转储。

非常感谢!

编辑:我有一个更新,显然下面给出的答案并不总是在python3.4下工作。如果我简单地使用协议1来选取值True,有时我只能恢复协议0 :-/

EN

回答 2

Stack Overflow用户

发布于 2013-11-06 17:48:14

您可以使用picketools创建自己的应用程序

代码语言:javascript
运行
复制
with open('your_pickle_file', 'rb') as fin:
    op, fst, snd = next(pickletools.genops(fin))
    proto = op.proto

似乎只将PROTO标记写为协议为2或更大的第一个元素。否则,第一个元素是指示协议是0还是1的标记或元素。

更新到更多的土地上:

代码语言:javascript
运行
复制
pops = pickletools.genops(pickle_source)
proto = 2 if next(pops)[0].proto == 2 else int(any(op.proto for op, fst, snd in pops))
票数 5
EN

Stack Overflow用户

发布于 2020-12-05 08:31:38

2020更新

我尝试了这里的方法(来自@JonClements的答案和评论),但似乎没有一个给我正确的协议。

但是,下面的方法是可行的:

代码语言:javascript
运行
复制
proto = None
op, fst, snd = next(pickletools.genops(data))
if op.name == 'PROTO':
    proto = fst

另一种选择(不酷,因为它解开了整个事情):

代码语言:javascript
运行
复制
out = io.StringIO()
pickletools.dis(data, out)
firstline = out.getvalue().splitlines()[0]
if ' PROTO ' in firstline:
    proto = re.sub(r'.*\s+', '', firstline)
    proto = int(proto)

应用程序:我想找出在pandas.to_hdf()中使用了什么pickle协议(如果使用了pickle,情况并不总是这样),而且,由于我不想分析HDF5文件的整个结构,所以我使用MonkeyPatch来监视pickle.loads()被要求反序列化的内容。

无论是谁通过谷歌搜索登陆这里,这都是我的全部(笨拙)设置:

代码语言:javascript
运行
复制
__pickle_loads = pickle.loads


def mock_pickle_loads(data):
    global max_proto_found
    op, fst, snd = next(pickletools.genops(data))
    if op.name == 'PROTO':
        proto = fst
        max_proto_found = max(max_proto_found, proto)
    return __pickle_loads(data)


def max_pklproto_hdf(hdf_filename):
    global max_proto_found
    max_proto_found = -1
    with MonkeyPatch().context() as m:
        m.setattr(pickle, 'loads', mock_pickle_loads)
        try:
            pd.read_hdf(hdf_filename)
        except ValueError:
            pass
    return max_proto_found
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19807790

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档