CodeGym /Cursos /Python SELF ES /Gestión de serialización

Gestión de serialización

Python SELF ES
Nivel 22 , Lección 2
Disponible

10.1 ¡Será a mi manera!

A veces tus objetos almacenan muchas referencias a diferentes objetos de servicio que no quieres enviar por la red, o que no es posible enviar por la red: referencias a archivos, bases de datos, etc.

Para que la serialización funcione también en estos casos, se ideó dar a la clase la capacidad de gestionar su propia serialización. Para esto se utilizan métodos especiales: __reduce__(), __getstate__(), __setstate__(). Estos métodos permiten especificar cómo los objetos deben ser serializados y restaurados.

Métodos principales de serialización controlada:

  • __reduce__(): Indica cómo debe ser serializado un objeto.
  • __getstate__(): Devuelve el estado del objeto para la serialización.
  • __setstate__(self, state): Restaura el objeto desde el estado.

A continuación, te contaré más sobre ellos y cómo usarlos juntos.

10.2 Método __reduce__()

El método __reduce__() devuelve una tupla, que indica cómo debe ser serializado y deserializado un objeto. La tupla usualmente contiene:

  • Una referencia a una función o clase que se usará para restaurar el objeto.
  • Una tupla de argumentos para esta función o clase.
  • Estado adicional del objeto (si es necesario).

Ejemplo:


import pickle

class CustomClass:
    def __init__(self, value):
        self.value = value
            
    def __reduce__(self):
        return (self.__class__, (self.value,))
            
    def __repr__(self):
        return f"CustomClass(value={self.value})"
            
# Creación del objeto
obj = CustomClass(42)
            
# Serialización del objeto
serialized_obj = pickle.dumps(obj)
print("Objeto serializado:", serialized_obj)
            
# Deserialización del objeto
deserialized_obj = pickle.loads(serialized_obj)
print("Objeto deserializado:", deserialized_obj)

Por defecto, la función __reduce__() tiene este comportamiento:


class CustomClass:
    def __init__(self, value):
        self.value = value
        
    def __reduce__(self):
        # Definición de la clase
        cls = self.__class__
        # Argumentos del constructor
        args = (self.value,)
        # Estado del objeto
        state = self.__dict__
        return (cls, args, state)

Devuelve una tupla que consta de tres objetos:

  • Referencia a la clase actual
  • Argumentos del constructor (tupla)
  • Referencia al estado actual del objeto

Si te satisface este comportamiento, no necesitas redefinir __reduce__().

10.3 Lectura y escritura de estado

Métodos __getstate__() y __setstate__()

Estos métodos se utilizan para gestionar el estado del objeto durante la serialización y deserialización.

  • __getstate__(): Devuelve el estado del objeto, que debe ser serializado.
  • __setstate__(self, state): Restaura el objeto desde el estado.

Ejemplo:

Supongamos que queremos guardar no todos los campos del objeto, sino excluir algunos de ellos. Para esto, en el método __getstate__() necesitamos:

  1. Copiar el estado actual del objeto (dado por el campo de servicio __dict__) en una variable separada: el diccionario state.
  2. Eliminar de él todos los campos que no necesitamos serializar.
  3. Devolver el objeto obtenido como resultado de la función __getstate__().

import pickle

class CustomClass:
    def __init__(self, value):
        self.value = value
        self.internal_state = "internal"
            
    def __getstate__(self):
        state = self.__dict__.copy()
        del state['internal_state']  # Excluimos el estado interno
        return state
            
    def __setstate__(self, state):
        self.__dict__.update(state)
        self.internal_state = "restored internal"  # Restauramos el estado interno
            
    def __repr__(self):
        return f"CustomClass(value={self.value}, internal_state={self.internal_state})"
            
# Creación del objeto
obj = CustomClass(42)
print("Objeto original:", obj)
            
# Serialización del objeto
serialized_obj = pickle.dumps(obj)
print("Objeto serializado:", serialized_obj)
            
# Deserialización del objeto
deserialized_obj = pickle.loads(serialized_obj)
print("Objeto deserializado:", deserialized_obj)

Durante la deserialización, en la función __setstate__(), hacemos dos cosas:

  1. Actualizamos el estado actual del objeto usando el método update().
  2. El campo internal_state (y otros campos no serializables) reciben nuevos valores.
1
Cuestionario/control
Trabajo con directorios, nivel 22, lección 2
No disponible
Trabajo con directorios
Trabajo con directorios
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION