Introducción al módulo Pickle de Python

El encurtido es un método popular para conservar los alimentos. Según Wikipedia, también es un procedimiento bastante antiguo, aunque se desconocen los orígenes del decapado,...

Introducción

El encurtido es un método popular de conservación de alimentos. Según Wikipedia, también es un procedimiento bastante antiguo, aunque se desconocen los orígenes del decapado, los antiguos mesopotámicos probablemente usaron el proceso hace 4400 años. Al colocar un producto en una solución específica, es posible aumentar drásticamente su vida útil. En otras palabras, es un método que nos permite almacenar alimentos para su posterior consumo.

Si es un desarrollador de Python, es posible que algún día necesite una forma de almacenar sus objetos de Python para su uso posterior. Bueno, ¿y si te dijera que también puedes encurtir objetos de Python?

Serialización

La serialización es un proceso de transformación de objetos o estructuras de datos en flujos de bytes o cadenas. Un flujo de bytes es, bueno, un flujo de bytes: un byte se compone de 8 bits de ceros y unos. Estos flujos de bytes se pueden almacenar o transferir fácilmente. Esto permite a los desarrolladores guardar, por ejemplo, los datos de configuración o el progreso del usuario y luego almacenarlos (en el disco o en una base de datos) o enviarlos a otra ubicación.

Los objetos de Python también se pueden serializar usando un módulo llamado Pepinillo.

Una de las principales diferencias entre encurtir objetos Python y encurtir verduras es el cambio inevitable e irreversible del sabor y la textura de los alimentos encurtidos. Mientras tanto, los objetos Python decapados se pueden decapar fácilmente para volver a su forma original. Este proceso, por cierto, se conoce universalmente como deserialización.

El decapado (o serialización en general) no debe confundirse con la compresión. El propósito del decapado es traducir los datos a un formato que pueda transferirse de la RAM al disco. La compresión, por otro lado, es un proceso de codificación de datos utilizando menos bits (para ahorrar espacio en disco).

La serialización es especialmente útil en cualquier software donde es importante poder guardar algo de progreso en el disco, salir del programa y luego volver a cargar el progreso después de volver a abrir el programa. Los videojuegos pueden ser el ejemplo más intuitivo de la utilidad de la serialización, pero hay muchos otros programas en los que guardar y cargar el progreso o los datos de un usuario es crucial.

Pickle frente a JSON

Existe la posibilidad de que haya oído hablar de JSON (Notación de objetos de JavaScript), que es un formato popular que también permite a los desarrolladores guardar y transmitir objetos codificados como cadenas. Este método de serialización tiene algunas ventajas sobre el decapado. El formato JSON es legible por humanos, independiente del idioma y más rápido que pickle.

Sin embargo, también tiene algunas limitaciones importantes. Lo que es más importante, de forma predeterminada, JSON solo puede representar un subconjunto limitado de tipos integrados de Python. Con Pickle, podemos serializar fácilmente un espectro muy amplio de tipos de Python y, lo que es más importante, clases personalizadas. Esto significa que no necesitamos crear un esquema personalizado (como lo hacemos para JSON) y escribir serializadores y analizadores propensos a errores. Todo el trabajo pesado se hace por ti con Pickle.

Lo que se puede encurtir y decapar {#lo que se puede decapar y decapar}

Los siguientes tipos se pueden serializar y deserializar utilizando el módulo Pickle:

  • Todos los tipos de datos nativos admitidos por Python (booleanos, Ninguno, enteros, flotantes, números complejos, cadenas, bytes, matrices de bytes)
  • Diccionarios, conjuntos, listas y tuplas, siempre que contengan objetos pickleables
  • Funciones y clases que se definen en el nivel superior de un módulo

Es importante recordar que el decapado no es un método de serialización independiente del idioma, por lo tanto, sus datos decapados solo pueden descifrarse mediante Python. Además, es importante asegurarse de que los objetos se decapan utilizando la misma versión de Python que se utilizará para decaparlos. Mezclar versiones de Python, en este caso, puede causar muchos problemas.

Además, las funciones se seleccionan por sus referencias de nombre y no por su valor. El pickle resultante no contiene información sobre el código o los atributos de la función. Por lo tanto, debe asegurarse de que el entorno en el que se deselecciona la función pueda importar la función. En otras palabras, si seleccionamos una función y luego la eliminamos en un entorno en el que no está definida o no se importa, se generará una excepción.

También es muy importante tener en cuenta que los objetos en escabeche se pueden utilizar de forma malévola. Por ejemplo, descifrar datos de una fuente no confiable puede resultar en la ejecución de un código malicioso.

Decapado de una lista de Python

El siguiente ejemplo muy simple muestra los conceptos básicos del uso del módulo Pickle en python 3:

1
2
3
4
5
6
import pickle

test_list = ['cucumber', 'pumpkin', 'carrot']

with open('test_pickle.pkl', 'wb') as pickle_out:
    pickle.dump(test_list, pickle_out)

Primero, tenemos que importar el módulo pickle, que se realiza en la línea 1. En la línea 3, definimos una lista simple de tres elementos que se decaparán.

En la línea 5 indicamos que el nombre de nuestro archivo pickle de salida será test_pickle.pkl. Al usar la opción wb, le decimos al programa que queremos escribir (w) datos binarios (b) dentro de él (porque queremos crear un flujo de bytes). Tenga en cuenta que la extensión pkl no es necesaria; la estamos usando en este tutorial porque esa es la extensión incluida en la documentación de Python.

En la línea 6 usamos el método pickle.dump() para seleccionar nuestra lista de pruebas y almacenarla dentro del archivo test_pickle.pkl.

Lo animo a que intente abrir el archivo pickle generado en su editor de texto. Notará rápidamente que un flujo de bytes definitivamente no es un formato legible por humanos.

Eliminación de una lista de Python

Ahora, eliminemos el contenido del archivo pickle de prueba y devolvamos nuestro objeto a su forma original.

1
2
3
4
5
6
import pickle

with open('test_pickle.pkl', 'rb') as pickle_in:
    unpickled_list = pickle.load(pickle_in)

print(unpickled_list)

Como puede ver, este procedimiento no es más complicado que cuando decapamos el objeto. En la línea 3 abrimos de nuevo nuestro archivo test_pickle.pkl, pero esta vez nuestro objetivo es leer (r) los datos binarios (b) almacenados en él.

A continuación, en la línea 5, usamos el método pickle.load() para deshacer nuestra lista y almacenarla en la variable unpickled_list.

Luego puede imprimir el contenido de la lista para ver por sí mismo que es idéntica a la lista que seleccionamos en el ejemplo anterior. Aquí está el resultado de ejecutar el código anterior:

1
2
$ python unpickle.py
['cucumber', 'pumpkin', 'carrot']

Decapado y decapado de objetos personalizados {#decapado y decapado de objetos personalizados}

Como mencioné antes, usando Pickle, puede serializar sus propios objetos personalizados. Echa un vistazo al siguiente ejemplo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import pickle

class Veggy():
    def __init__(self):
        self.color = ''
    def set_color(self, color):
        self.color = color

cucumber = Veggy()
cucumber.set_color('green')

with open('test_pickle.pkl', 'wb') as pickle_out:
    pickle.dump(cucumber, pickle_out)

with open('test_pickle.pkl', 'rb') as pickle_in:
    unpickled_cucumber = pickle.load(pickle_in)

print(unpickled_cucumber.color)

Como puedes ver, este ejemplo es casi tan simple como el anterior. Entre las líneas 3 y 7 definimos una clase simple que contiene un atributo y un método que cambia este atributo. En la línea 9 creamos una instancia de esa clase y la almacenamos en la variable pepino, y en la línea 10 establecemos su atributo color en "verde".

Luego, utilizando exactamente las mismas funciones que en el ejemplo anterior, encurtimos y desencurtamos nuestro objeto pepino recién creado. Ejecutar el código anterior da como resultado el siguiente resultado:

1
2
$ python unpickle_custom.py
green

Recuerde, que solo podemos deshacer el objeto en un entorno donde la clase Veggy está definida o importada. Si creamos un nuevo script e intentamos deshacer el objeto sin importar la clase Veggy, obtendremos un "AttributeError". Por ejemplo, ejecute el siguiente script:

1
2
3
4
5
6
import pickle

with open('test_pickle.pkl', 'rb') as pickle_in:
    unpickled_cucumber = pickle.load(pickle_in)

print(unpickled_cucumber.color)

En el resultado del script anterior, verá el siguiente error:

1
2
3
4
5
$ python unpickle_simple.py
Traceback (most recent call last):
  File "<pyshell#40>", line 2, in <module>
    unpickled_cucumber = pickle.load(pickle_in)
AttributeError: Can't get attribute 'Veggy' on <module '__main__' (built-in)>

Conclusión

Como puede ver, gracias al módulo Pickle, la serialización de objetos de Python es bastante simple. En nuestros ejemplos, seleccionamos una lista simple de Python, pero puede usar exactamente el mismo método para guardar un amplio espectro de tipos de datos de Python, siempre que se asegure de que sus objetos contengan solo otros objetos seleccionables.

El decapado tiene algunas desventajas, la mayor de las cuales podría ser el hecho de que solo puede descifrar sus datos usando Python; si necesita una solución multilingüe, JSON es definitivamente una mejor opción. Y finalmente, recuerda que los pickles se pueden usar para llevar el código que no necesariamente quieres ejecutar. De manera similar a los alimentos encurtidos, siempre que obtenga sus encurtidos de fuentes confiables, debería estar bien. star bien.

Licensed under CC BY-NC-SA 4.0