tipos - ¿Elección del protocolo Pickle de Python?
try except python ejemplos (2)
Yo uso python 2.7 y trato de recuperar un objeto. Me pregunto cuál es la verdadera diferencia entre los protocolos de pickle.
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
luego encontré que los archivos guardados tienen diferentes tamaños en el disco:
-
noProt
: 177.6MB -
prot0
: 177.6MB -
prot1
: 44.4MB -
prot2
: 44.4MB
Sé que prot0
es un archivo de texto legible por humanos, así que no quiero usarlo. Supongo que el protocolo 0 es el predeterminado.
Me pregunto cuál es la diferencia entre los protocolos 1 y 2, ¿hay alguna razón por la que deba elegir uno u otro?
¿Cuál es el mejor para usar, pickle
o cPickle
?
De la documentación del formato de datos del módulo pickle
:
Actualmente hay 3 protocolos diferentes que se pueden usar para conservar en vinagre.
- La versión de protocolo 0 es el protocolo ASCII original y es compatible con versiones anteriores de Python.
- La versión de protocolo 1 es el formato binario anterior que también es compatible con versiones anteriores de Python.
- La versión 2 del protocolo se introdujo en Python 2.3. Proporciona un encurtido mucho más eficiente de las clases de nuevo estilo.
[...]
Si no se especifica un protocolo, se usa el protocolo 0. Si el protocolo se especifica como valor negativo o
HIGHEST_PROTOCOL
, seHIGHEST_PROTOCOL
la versión de protocolo más alta disponible.
Seguir con el protocolo versión 2, especialmente si está utilizando clases personalizadas derivadas de object
(clases de estilo nuevo). Cuál es el código más moderno, en estos días.
A menos que necesite mantener la compatibilidad con versiones antiguas de Python, es más fácil simplemente quedarse con la versión de protocolo más alta que puede tener en sus manos:
with open("prot2", ''wb'') as pfile:
pickle.dump(d, pfile, protocol=pickle.HIGHEST_PROTOCOL)
¡Debido a que este es un formato binario, asegúrese de usar ''wb''
como el modo de archivo!
cPickle
y pickle
son en su mayoría compatibles; las diferencias radican en la API ofrecida. Para la mayoría de los casos de uso, simplemente quédate con cPickle
; es mas rapido. Citando la documentation nuevamente:
En primer lugar,
cPickle
puede ser hasta 1000 veces más rápido que pickle porque el primero se implementa en C. En segundo lugar, en el módulocPickle
loscPickle
Pickler()
yUnpickler()
son funciones, no clases. Esto significa que no puede usarlos para derivar subcapas de decapado personalizadas y descortezadas. La mayoría de las aplicaciones no necesitan esta funcionalidad y deberían beneficiarse del rendimiento enormemente mejorado del módulocPickle
.
Para las personas que usan Python 3, hay, a partir de Python 3.5, cinco protocolos posibles para elegir:
Actualmente hay 5 protocolos diferentes que se pueden usar para conservar en vinagre. Cuanto mayor sea el protocolo utilizado, más reciente será la versión de Python necesaria para leer el pickle producido [ doc ]:
La versión de protocolo 0 es el protocolo original "legible por humanos" y es compatible con versiones anteriores de Python.
La versión de protocolo 1 es un formato binario antiguo que también es compatible con versiones anteriores de Python.
- La versión 2 del protocolo se introdujo en Python 2.3. Proporciona un encurtido mucho más eficiente de las clases de nuevo estilo. Consulte PEP 307 para obtener información sobre las mejoras introducidas por el protocolo 2.
- La versión 3 del protocolo se agregó en Python 3.0. Tiene soporte explícito para objetos de bytes y Python 2.x no puede desmantelarlo. Este es el protocolo predeterminado y el protocolo recomendado cuando se requiere compatibilidad con otras versiones de Python 3.
- La versión 4 del protocolo se agregó en Python 3.4. Agrega soporte para objetos muy grandes, decapando más tipos de objetos y algunas optimizaciones de formato de datos. Consulte PEP 3154 para obtener información sobre las mejoras introducidas por el protocolo 4.
Una regla general es que debe usar el protocolo más alto posible que sea retrocompatible con aquello para lo que desea usarlo. Por lo tanto, si desea que sea compatible con versiones anteriores de Python 2, entonces la versión de protocolo 2 es una buena opción, si desea que sea compatible con todas las versiones de Python, entonces la versión 1 es buena. Si no te importa la compatibilidad con versiones anteriores, el uso de pickle.HIGHEST_PROTOCOL
te brinda automáticamente el protocolo más alto para tu versión de Python.
También en Python 3, la importación de pickle
importa automáticamente la implementación C.
Otro punto a tener en cuenta en términos de compatibilidad es que, por defecto, los protocolos 3 y 4 usan la codificación Unicode de cadenas mientras que los protocolos anteriores no. Por lo tanto, en Python 3, si carga un archivo encurtido que fue escalado en Python 2, probablemente tendrá que especificar explícitamente la codificación para cargarlo correctamente.