Introducción al módulo de Python Pickle

I

Introducción

Decapado es un método popular de conservación de alimentos. De acuerdo a 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 Python?

Publicación por entregas

La serialización es un proceso de transformación de objetos o estructuras de datos en flujos de bytes o Strings. 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 un 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 de Python en escabeche se pueden quitar fácilmente a su forma original. Este proceso, por cierto, se conoce universalmente como deserialización.

Decapado (o publicación por entregas en general) no debe confundirse con compresión. El propósito del decapado es traducir los datos a un formato que se pueda transferir 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 en el que 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 vs JSON

Existe la posibilidad de que hayas oído hablar JSON (JavaScript Object Notation), 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 lenguaje y más rápido que pickle.

Sin embargo, también tiene algunas limitaciones importantes. Lo más importante es que, de forma predeterminada, JSON solo puede representar un subconjunto limitado de tipos integrados de Python. Con Pickle, podemos serializar fácilmente un amplio espectro 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 está hecho para ti con Pickle.

¿Qué se puede encurtir y sin 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 encurtidos.
  • 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 lenguaje, por lo tanto, los datos encurtidos solo se pueden deshacer con Python. Además, es importante asegurarse de que los objetos se conserven utilizando la misma versión de Python que se utilizará para eliminarlos. 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. La salmuera 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 elimine la función pueda importar la función. En otras palabras, si seleccionamos una función y luego la desechamos en un entorno donde 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 usar de manera malévola. Por ejemplo, eliminar 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:

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 pickle módulo, que se hace en la línea 1. En la línea 3 definimos una lista simple de tres elementos que serán decapados.

En la línea 5 indicamos que el nombre de nuestro archivo pickle de salida será test_pickle.pkl. Usando el wb opción, 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 el pkl la extensión 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 pickle.dump() método para encurtir nuestra lista de prueba y almacenarla dentro del test_pickle.pkl archivo.

Le 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.

Eliminando una lista de Python

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

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 encurtimos el objeto. En la línea 3 abrimos nuestro test_pickle.pkl archivo de nuevo, pero esta vez nuestro objetivo es leer (r) los datos binarios (b) almacenados en su interior.

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

A continuación, puede imprimir el contenido de la lista para comprobar 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:

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

Decapado y despepitado de objetos personalizados

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

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 puede 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 el cucumber variable, y en la línea 10 establecemos su atributo color a “verde”.

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

$ python unpickle_custom.py
green

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

import pickle

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

print(unpickled_cucumber.color)

En la salida del script anterior, verá el siguiente error:

$ 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 Python es bastante simple. En nuestros ejemplos, seleccionamos una lista de Python simple, 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 que se pueden encurtir.

Pickling tiene algunas desventajas, la mayor de las cuales podría ser el hecho de que solo puede eliminar sus datos usando Python; si necesita una solución de idiomas cruzados, JSON es definitivamente una mejor opción. Y finalmente, recuerde que los pickles pueden usarse para llevar el código que no necesariamente desea ejecutar. De manera similar a la comida en escabeche, siempre que los obtenga de fuentes confiables, debería estar bien.

 

About the author

Ramiro de la Vega

Bienvenido a Pharos.sh

Soy Ramiro de la Vega, Estadounidense con raíces Españolas. Empecé a programar hace casi 20 años cuando era muy jovencito.

Espero que en mi web encuentres la inspiración y ayuda que necesitas para adentrarte en el fantástico mundo de la programación y conseguir tus objetivos por difíciles que sean.

Add comment

Sobre mi

Últimos Post

Etiquetas

Esta web utiliza cookies propias para su correcto funcionamiento. Al hacer clic en el botón Aceptar, aceptas el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Más información
Privacidad