Как я могу засолить результаты пены?
Чтобы избежать повторного доступа к SOAP-серверу во время разработки, я пытаюсь кэшировать результаты, чтобы я мог запускать остальную часть своего кода, не запрашивая сервер каждый раз.
С кодом ниже я получаю PicklingError: Can't pickle <class suds.sudsobject.AdvertiserSearchResponse at 0x03424060>: it's not found as suds.sudsobject.AdvertiserSearchResponse
когда я пытаюсь засолить результат. Я думаю, это потому, что классы создаются динамически.
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()
Если я уроню -1
версия протокола от pickle.dump(result, file, -1)
Я получаю другую ошибку:
TypeError: a class that defines __slots__ without defining __getstate__ cannot be pickled
Травление - это то, что нужно делать? Могу ли я заставить его работать? Есть ли способ лучше?
2 ответа
Поскольку сообщение об ошибке, которое вы получаете в настоящее время, пытается вам сообщить, вы пытаетесь выбрать экземпляры, которые нельзя выбрать (в древнем устаревшем протоколе выбора, который вы сейчас используете), потому что их класс определяет __slots__
но не __getstate__
метод.
Однако даже изменение их класса не поможет, потому что тогда вы столкнетесь с другой проблемой - которую вы уже правильно определили как вероятную из-за динамически генерируемых классов. Все pickle
протоколы сериализуют классы (и функции) "по имени", по существу ограничивая их нахождение в именах верхнего уровня в своих модулях. И сериализация экземпляра абсолютно требует сериализации класса (как еще вы могли бы восстановить экземпляр позже, если класса не было?!).
Таким образом, вам нужно будет сохранить и перезагрузить данные другим способом, нарушив текущую прямую зависимость от конкретных классов в suds.sudsobject
в пользу зависимости от интерфейса (либо формализованного, либо просто определенного с помощью утки), который может быть реализован как такими конкретными классами, когда вы на самом деле получаете доступ к SOAP-серверу, так и более простыми "домашними", когда вы загружаете данные из файл. (Данные, представляющие состояние экземпляра, без сомнения, могут быть представлены как dict, так что вы можете вызвать их через pickle, если вы действительно хотите, например, через copy_reg
модуль, который позволяет вам настраивать сериализацию / десериализацию протоколов для объектов, которые вы вынуждены обрабатывать неинвазивно [[поэтому вы не можете обойтись без добавления __getstate__
или что-то подобное их классам]] - проблема возникнет только в том случае, если среди таких объектов есть богатая сетка взаимных ссылок).
Вы выбираете сам объект класса, а не объекты экземпляра класса. Это не будет работать, если объект класса воссоздан. Однако выборка экземпляров класса будет работать, пока существует объект класса.