有时 pickle 堆会出乎意料地大。假设我可以成功地 pickle 和 unpickle 一个对象,有没有办法检查转储并准确查看包含的内容?
Pickled 对象包括数据但不包括代码。如果我没有编写代码,并且对象很复杂(例如,带有访问器的自定义类的实例,以及对其他数据的大量引用),则可能很难识别转储中包含的内容并因此占用很大的空间。因此这个问题。
最佳答案
内置pickletools模块可以输出有关 pickle 文件中表示的每个操作码的信息。当从命令行使用或与 dis
一起使用时,它会以可读格式输出操作码。文档中的示例:
For example, with a tuple (1, 2) pickled in file x.pickle:
$ 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,因此检查数据是安全的。
关于python - 如何查看 pickle 转储中包含哪些数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31320265/