Módulo Pickle de Python
En el desarrollo con Python, a menudo necesitamos guardar los objetos en tiempo de ejecución o restaurar el estado anterior después de reiniciar el programa, por ejemplo:
- Cachear resultados de cálculos en disco para evitar cálculos repetidos
- Guardar configuraciones de usuario y estados intermedios del programa
- Transferir objetos complejos entre diferentes procesos de Python
pickleEl módulo es precisamente lo que Python proporciona para resolver este tipo de problemasla solución oficial integrada.。
de PythonpickleEl módulo es una biblioteca estándar para serializar y deserializar objetos de Python.
Antes de comenzar a usar Pickle, es necesario entender dos conceptos clave:
- Serialización (Pickling): convertir objetos de Python en secuencias de bytes
- Deserialización (Unpickling): convertir secuencias de bytes de vuelta a objetos de Python
pickleEl módulo puede guardar casi todos los objetos de Python (como listas, diccionarios, instancias de clases, etc.) en archivos, o transmitirlos a través de la red, y luego recargarlos cuando sea necesario.
¿Por qué usar el módulo Pickle?
- Persistencia de datos: guardar objetos de Python en archivos para poder acceder a estos datos incluso después de cerrar el programa.
- Transferencia de datos: transmitir objetos de Python a través de la red, por ejemplo, para pasar datos en sistemas distribuidos.
- Almacenamiento y carga rápidos:
pickleEl módulo puede manejar estructuras de datos complejas de manera eficiente, adecuado para escenarios que requieren almacenamiento y carga rápidos.
Casos de uso típicos de Pickle
pickleMuy adecuado para los siguientes escenarios:
- Persistencia de datos local
- Guardar y restaurar el estado de ejecución del programa
- Cache de resultados de cálculos intermedios
- Comunicación entre procesos de Python (IPC)
- Guardado de modelos de aprendizaje automático y datos de características
Escenarios no adecuados:
- Intercambio de datos entre lenguajes
- Transmisión de datos en interfaces entre frontend y backend
- Deserialización de fuentes de datos no confiables
¿Qué objetos admite Pickle?
1. Tipos de objetos compatibles
| Tipo | ¿Compatible? |
|---|---|
| int / float / bool / str | Compatible |
| list / tuple / dict / set | Compatible |
| None | Compatible |
| Instancias de clases personalizadas | Compatible |
| Estructuras anidadas | Compatible |
Objetos no compatibles o no recomendados
- Objetos de archivo abiertos
- sockets, conexiones de bases de datos
- Recursos del sistema operativo
- Objetos que dependen del estado del entorno de ejecución
Importar el módulo
Usar el módulo Pickle es muy sencillo, solo necesita importarlo:
import pickle
Uso básico del módulo Pickle
1. Serializar objetos
Usandopickle.dump()el método puede serializar objetos de Python y guardarlos en un archivo.
Ejemplo
# Crear un objeto de Python
data = {
'name': 'Alice',
'age': 25,
'hobbies': ['reading', 'traveling']
}
# Serializar el objeto y guardarlo en un archivo
with open('data.pkl', 'wb') as file:
pickle.dump(data, file)
'wb'Indica abrir el archivo en modo de escritura binaria.pickle.dump()va adataEl objeto se serializa y se escribe en el archivo.
2. Deserializar objetos
Usandopickle.load()el método puede cargar y deserializar objetos de Python desde un archivo.
Ejemplo
# Cargar y deserializar el objeto desde el archivo
with open('data.pkl', 'rb') as file:
loaded_data = pickle.load(file)
print(loaded_data)
'rb'Indica abrir el archivo en modo de lectura binaria.pickle.load()Lee el flujo de bytes del archivo y lo deserializa en un objeto de Python.
3. Serializar a una cadena de bytes
Si no desea guardar en un archivo, puede usar pickle.dumps() para serializar el objeto en una cadena de bytes:
Ejemplo
data = [1, 2, 3, 4, 5]
# Serializar a una cadena de bytes
byte_data = pickle.dumps(data)
print(byte_data)
# Salida similar a: b'\x80\x04\x95\x0f\x00\x00\x00...'
4. Deserializar desde una cadena de bytes
Puede usar pickle.loads() para deserializar objetos desde una cadena de bytes:
Ejemplo
byte_data = b'\x80\x04\x95\x0f\x00\x00\x00\x00\x00\x00\x00]\x94(K\x01K\x02K\x03K\x04K\x05e.'
# Deserializar desde la cadena de bytes
original_data = pickle.loads(byte_data)
print(original_data)
# Salida: [1, 2, 3, 4, 5]
5. Tipos de objetos que se pueden serializar
Pickle puede serializar la mayoría de los objetos de Python, incluyendo:
- Tipos de datos básicos: enteros, flotantes, cadenas, booleanos, None
- Tipos de colección: listas, tuplas, diccionarios, conjuntos
- Instancias de clases personalizadas
- Funciones y clases (con ciertas limitaciones)
Ejemplo
# Serializar datos de diferentes tipos
numbers = [1, 2, 3]
text = "Hello, Pickle"
dictionary = {'key': 'value'}
tuple_data = (1, 2, 3)
set_data = {1, 2, 3}
# Poner todos los datos en una lista
all_data = [numbers, text, dictionary, tuple_data, set_data]
# Serializar
with open('mixed_data.pkl', 'wb') as f:
pickle.dump(all_data, f)
# Deserializar
with open('mixed_data.pkl', 'rb') as f:
loaded_data = pickle.load(f)
print(loaded_data)
6. Serializar clases personalizadas
Pickle puede manejar bien las instancias de clases personalizadas:
Ejemplo
class Student:
def __init__(self, name, age, grade):
self.name = name
self.age = age
self.grade = grade
def __repr__(self):
return f"Student(name={self.name}, age={self.age}, grade={self.grade})"
# Crear instancia
student = Student("Li Si", 20, "Tercer año")
# Serializar
with open('student.pkl', 'wb') as f:
pickle.dump(student, f)
# Deserializar
with open('student.pkl', 'rb') as f:
loaded_student = pickle.load(f)
print(loaded_student)
# Salida: Student(name=Li Si, age=20, grade=Tercer año)
7. Serializar múltiples objetos
Puede llamar a pickle.dump() varias veces para guardar múltiples objetos:
Ejemplo
data1 = {'item': 'apple', 'count': 5}
data2 = ['banana', 'orange', 'grape']
data3 = 42
# Guardar múltiples objetos
with open('multiple.pkl', 'wb') as f:
pickle.dump(data1, f)
pickle.dump(data2, f)
pickle.dump(data3, f)
# Leer múltiples objetos (el orden debe ser el mismo)
with open('multiple.pkl', 'rb') as f:
loaded_data1 = pickle.load(f)
loaded_data2 = pickle.load(f)
loaded_data3 = pickle.load(f)
print(loaded_data1)
print(loaded_data2)
print(loaded_data3)
8. Ejemplos de aplicación práctica
Ejemplo 1: Guardar y cargar la configuración de un modelo de aprendizaje automático
Ejemplo
# Simular la configuración de un modelo de aprendizaje automático
model_config = {
'model_type': 'RandomForest',
'n_estimators': 100,
'max_depth': 10,
'trained_date': '2024-01-13',
'accuracy': 0.95
}
# Guardar configuración
with open('model_config.pkl', 'wb') as f:
pickle.dump(model_config, f)
# Cargar configuración
with open('model_config.pkl', 'rb') as f:
config = pickle.load(f)
print(f"Tipo de modelo: {config['model_type']}")
print(f"Precisión: {config['accuracy']}")
Ejemplo 2: Cachear resultados de cálculos
Ejemplo
import os
def expensive_computation(n):
"""Simular un cálculo que consume tiempo"""
result = sum(i ** 2 for i in range(n))
return result
def compute_with_cache(n, cache_file='cache.pkl'):
# Verificar si el caché existe
if os.path.exists(cache_file):
with open(cache_file, 'rb') as f:
cache = pickle.load(f)
if n in cache:
print("Leyendo el resultado desde el caché")
return cache[n]
else:
cache = {}
# Realizar el cálculo
print("Realizando el cálculo...")
result = expensive_computation(n)
# Guardar en el caché
cache[n] = result
with open(cache_file, 'wb') as f:
pickle.dump(cache, f)
return result
# Ejemplo de uso
print(compute_with_cache(1000000)) # La primera vez calculará
print(compute_with_cache(1000000)) # La segunda vez leerá desde el caché
Precauciones del módulo Pickle
- Seguridad:
pickleEl módulo ejecuta código arbitrario al deserializar, por lo tanto no carguepickledatos de fuentes no confiables, para evitar ataques maliciosos. - Compatibilidad:
pickleEl flujo de bytes generado es específico de Python, y puede haber problemas de compatibilidad entre diferentes versiones de Python. - Rendimiento: Para conjuntos de datos grandes,
picklela serialización y deserialización de pickle pueden ser lentas; se puede considerar el uso de herramientas de serialización más eficientes, comojsonomsgpack。
Uso avanzado: serialización de objetos personalizados
pickleEl módulo admite la serialización de clases personalizadas. De forma predeterminada,picklese guardan los atributos del objeto y el nombre de la clase. Si se necesita una lógica de serialización más compleja, se puede implementar en la clase__getstate__()y__setstate__()el método.
Ejemplo
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __getstate__(self):
# Lógica de serialización personalizada
return {'name': self.name, 'age': self.age}
def __setstate__(self, state):
# Lógica de deserialización personalizada
self.name = state['name']
self.age = state['age']
# Crear objeto y serializar
person = Person('Bob', 30)
with open('person.pkl', 'wb') as file:
pickle.dump(person, file)
# Deserializar objeto
with open('person.pkl', 'rb') as file:
loaded_person = pickle.load(file)
print(loaded_person.name, loaded_person.age)
Métodos comunes del módulo pickle
| Método | Descripción | Ejemplo |
|---|---|---|
pickle.dump(obj, file) | Serializar el objeto y escribirlo en un archivo | pickle.dump(data, open('data.pkl', 'wb')) |
pickle.load(file) | Leer de un archivo y deserializar el objeto | data = pickle.load(open('data.pkl', 'rb')) |
pickle.dumps(obj) | Serializar el objeto en una cadena de bytes | bytes_data = pickle.dumps([1, 2, 3]) |
pickle.loads(bytes) | Deserializar el objeto desde una cadena de bytes | lst = pickle.loads(bytes_data) |
pickle.HIGHEST_PROTOCOL | La versión de protocolo más alta disponible (atributo) | pickle.dump(..., protocol=pickle.HIGHEST_PROTOCOL) |
pickle.DEFAULT_PROTOCOL | Versión de protocolo predeterminada (atributo, normalmente 4) | pickle.dumps(obj, protocol=pickle.DEFAULT_PROTOCOL) |
1. Serializar objeto a archivo
Ejemplo
data = {'name': 'Alice', 'age': 25}
with open('data.pkl', 'wb') as f:
pickle.dump(data, f, protocol=pickle.HIGHEST_PROTOCOL)
2. Deserializar desde archivo
Ejemplo
loaded_data = pickle.load(f)
print(loaded_data) # Salida: {'name': 'Alice', 'age': 25}
3. Serializar a cadena de bytes (transmisión por red/caché)
Ejemplo
restored_list = pickle.loads(bytes_data)
Versiones de protocolo del módulo pickle
| Versión de protocolo | Descripción |
|---|---|
| 0 | Formato ASCII legible por humanos (compatible con versiones antiguas) |
| 1 | Formato binario (compatible con versiones antiguas) |
| 2 | Python 2.3+ optimizado con soporte para objetos de clase |
| 3 | Python 3.0+ protocolo predeterminado (no compatible con Python 2) |
| 4 | Python 3.4+ soporta objetos más grandes y más tipos de datos |
| 5 | Python 3.8+ soporta optimización de memoria y compartición de datos |