有时泡菜转储意外大。假设我可以成功地对一个对象进行pickle和unpickle,有没有办法检查转储并查看确切包含的内容?
腌制对象包括数据,但不包括代码。如果我没有编写代码,并且对象很复杂(例如,具有访问器的自定义类的实例,以及对其他数据的大量引用),则可能很难识别转储中包含的内容并将其占用很多空间。因此这个问题。
答案 0 :(得分:2)
内置pickletools模块可以输出有关pickle文件中表示的每个操作码的信息。从命令行或dis
使用时,它以可读格式输出操作码。文档中的示例:
例如,在文件x.pickle中腌制的元组(1,2):
$ python -m pickle x.pickle (1, 2) $ python -m pickletools x.pickle 0: \x80 PROTO 3 2: K BININT1 1 4: K BININT1 2 6: \x86 TUPLE2 7: q BINPUT 0 9: . STOP highest protocol among opcodes = 2
要获得有关操作码的详细信息,请查看code2op
词典。使用genops
迭代pickle数据以及此详细信息。例如,上面的\x86 TUPLE2
表示:
>>> print(pickletools.code2op['\x86'].doc)
Build a two-tuple out of the top two items on the stack.
This code pops two values off the stack and pushes a tuple of
length 2 whose items are those values back onto it. In other
words:
stack[-2:] = [tuple(stack[-2:])]
请注意,虽然pickle可能不安全(因为它可以执行任意代码),但是在反汇编时实际上并没有加载pickle,因此检查数据是安全的。