¿Cómo puedo decantar los resultados de la espuma?

Para evitar acceder repetidamente a un servidor SOAP durante el desarrollo, estoy tratando de almacenar en caché los resultados para poder ejecutar el rest de mi código sin consultar el servidor cada vez.

Con el código que PicklingError: Can't pickle : it's not found as suds.sudsobject.AdvertiserSearchResponse continuación, obtengo un PicklingError: Can't pickle : it's not found as suds.sudsobject.AdvertiserSearchResponse cuando trato de PicklingError: Can't pickle : it's not found as suds.sudsobject.AdvertiserSearchResponse un resultado. Supongo que esto es porque las clases son creadas dinámicamente.

 import pickle from suds.client import Client client = Client(...) result = client.service.search(...) file = open('test_pickle.dat', 'wb') pickle.dump(result, file, -1) file.close() 

Si pickle.dump(result, file, -1) versión del protocolo -1 de pickle.dump(result, file, -1) , pickle.dump(result, file, -1) un error diferente:

 TypeError: a class that defines __slots__ without defining __getstate__ cannot be pickled 

¿Es lo correcto hacer el decapado? ¿Puedo hacer que funcione? ¿Hay alguna manera mejor?

Como el mensaje de error que está recibiendo actualmente está tratando de decirle, está tratando de capturar instancias que no son extraíbles (en el antiguo protocolo de salmuera heredado que está usando ahora) porque su clase define __slots__ pero no un método __getstate__ .

Sin embargo, incluso alterar su clase no ayudaría porque entonces se encontraría con el otro problema, que ya identificó correctamente debido a las clases generadas dinámicamente. Todos los protocolos de pickle serializan las clases (y funciones) “por nombre”, esencialmente limitándolos a estar en los nombres de nivel superior en sus módulos. Y, la serialización de una instancia requiere absolutamente la serialización de la clase (¡¿de qué otra manera podría reconstruir la instancia más adelante si la clase no existiera ?!).

Por lo tanto, deberá guardar y volver a cargar sus datos de alguna otra manera, rompiendo su dependencia directa actual de las clases concretas en suds.sudsobject a favor de depender de una interfaz (ya sea formalizada o simplemente definida por tipificación de pato) que se puede implementar tanto por esas clases concretas cuando de hecho está accediendo al servidor SOAP, o más simples “hechas en casa” cuando está cargando los datos de un archivo. (Los datos que representan el estado de la instancia pueden sin duda representarse como un dict, por lo que puede forzarlo a través de pickle si realmente lo desea, por ejemplo, a través del módulo copy_reg que le permite personalizar protocolos de serialización / deserialización para objetos que debe forzar de manera no invasiva [[por lo que no puede ir agregando __getstate__ o similar a sus clases]], el problema vendrá solo si hay una rica malla de referencias mutuas entre tales objetos).

Usted está decapando el objeto de la clase en sí, y no los objetos de instancia de la clase. Esto no funcionará si se recrea el objeto de clase. Sin embargo, las instancias de decapado de la clase funcionarán mientras exista el objeto de la clase.