Python pickle协议选择?

Cob*_*bry 56 python numpy pickle python-2.7

我使用python 2.7并试图挑选一个对象.我想知道泡菜协议之间真正的区别是什么.

import numpy as np
import pickle
class data(object):
    def __init__(self):
        self.a = np.zeros((100, 37000, 3), dtype=np.float32)

d = data()
print "data size: ", d.a.nbytes/1000000.
print "highest protocol: ", pickle.HIGHEST_PROTOCOL
pickle.dump(d,open("noProt", 'w'))
pickle.dump(d,open("prot0", 'w'), protocol=0)
pickle.dump(d,open("prot1", 'w'), protocol=1)
pickle.dump(d,open("prot2", 'w'), protocol=2)


out >> data size:  44.4
out >> highest protocol:  2
Run Code Online (Sandbox Code Playgroud)

然后我发现保存的文件在磁盘上有不同的大小:

  • noProt:177.6MB
  • prot0:177.6MB
  • prot1:44.4MB
  • prot2:44.4MB

我知道这prot0是一个人类可读的文本文件,所以我不想使用它.我猜协议0是默认给出的协议.

我想知道协议1和协议2之间的区别是什么,我有理由选择其中一个或另一个吗?

什么是更好用,picklecPickle

Mar*_*ers 47

pickle模块数据格式文档:

目前有3种不同的方案可用于酸洗.

  • 协议版本0是原始的ASCII协议,并且向后兼容早期版本的Python.
  • 协议版本1是旧的二进制格式,它也与早期版本的Python兼容.
  • 在Python 2.3中引入了协议版本2.它提供了更有效的新式类型的酸洗.

[...]

如果一个协议没有指定,协议0被使用.如果将protocol指定为负值HIGHEST_PROTOCOL,则将使用可用的最高协议版本.

坚持使用协议版本2,特别是如果您使用从object(新式类)派生的自定义类.这些天最现代的代码.

除非你需要保持与旧版Python版本的向后兼容性,否则最简单的方法就是坚持使用你能掌握的最高协议版本:

with open("prot2", 'wb') as pfile:
    pickle.dump(d, pfile, protocol=pickle.HIGHEST_PROTOCOL)
Run Code Online (Sandbox Code Playgroud)

因为这是二进制格式,所以一定要'wb'用作文件模式!

cPickle并且pickle大部分兼容; 差异在于提供的API.对于大多数用例,只需坚持cPickle; 它更快.再次引用文档:

首先,cPickle可高达1000倍,比泡菜更快,因为前者是C.第二实施中,在cPickle模块的可调用Pickler()Unpickler()是函数,不是类.这意味着您无法使用它们来派生自定义pickle和unpickling子类.大多数应用程序不需要此功能,并且应该从cPickle模块的大大改进的性能中受益.

  • “ pickle”是Python 3中的C版本,Python 3.4使用协议3,其速度[是协议2的两倍](http://stackoverflow.com/a/26860404/819417)。 (2认同)

pat*_*_ai 18

对于使用Python 3的人来说,从Python 3.5开始,有五种可能的协议可供选择:

目前有5种不同的方案可用于酸洗.使用的协议越高,读取生成的pickle所需的Python版本越新[ doc ]:

  • 协议版本0是原始的"人类可读"协议,并且向后兼容早期版本的Python.

  • 协议版本1是旧的二进制格式,它也与早期版本的Python兼容.

  • 在Python 2.3中引入了协议版本2.它提供了更有效的新式类型的酸洗.有关协议2带来的改进的信息,请参阅PEP 307.
  • 在Python 3.0中添加了协议版本3.它具有对字节对象的显式支持,并且不能被Python 2.x打开.这是默认协议,需要与其他Python 3版本兼容时的推荐协议.
  • 在Python 3.4中添加了协议版本4.它增加了对非常大的对象的支持,挑选更多种类的对象,以及一些数据格式优化.有关协议4带来的改进的信息,请参阅PEP 3154.

一般规则是您应该使用与您想要使用它的后向兼容的最高协议.因此,如果您希望它向后兼容Python 2,那么协议版本2是一个不错的选择,如果您希望它与所有Python版本向后兼容,那么版本1是好的.如果您不关心向后兼容性,那么使用pickle.HIGHEST_PROTOCOL自动为您提供Python版本的最高协议.

同样在Python 3中,导入会pickle自动导入C实现.

在兼容性方面需要注意的另一点是,默认情况下,协议3和4使用字符串的unicode编码,而早期协议则不使用.所以在Python 3中,如果你加载一个在Python 2中腌制的pickle文件,你可能必须明确指定编码才能正确加载它.