我如何泡泡沫结果?
为了避免在开发过程中反复访问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()
如果我放弃从pickle.dump(result, file, -1)
的-1
协议版本,我得到一个不同的错误:
TypeError: a class that defines __slots__ without defining __getstate__ cannot be pickled
是酸洗做正确的事?我可以使它工作吗?有没有更好的办法?
由于您目前得到的是想告诉你的错误信息,你要腌那些不 picklable(在你现在正在使用的古代遗留下来的泡菜协议)的情况下,因为它们的类定义__slots__
但不是__getstate__
方法。
然而,即使改变他们的班级也没有帮助,因为那么你会遇到其他问题 - 您已经正确识别出可能是由于动态生成的类。所有pickle
协议“按名称”序列化类(和函数),基本上将它们限制在其模块中的*名称。并且,序列化一个实例绝对是是否需要序列化类(如果类不在周围,你怎么可能重建实例?)。
因此,您需要以其他方式保存和重新加载数据,从而打破当前对suds.sudsobject
中具体类的直接依赖,转而依赖于接口(可以是形式化的或仅由duck typing定义的)当您实际访问SOAP服务器时,由这些具体类实现,或者当您从文件加载数据时,实现更简单的“自制”类。 (表示实例状态的数据无疑可以表示为字典,所以如果您真的想要,可以通过pickle强制执行它,例如通过copy_reg
模块,它允许您为必须处理的对象定制序列化/反序列化协议非侵入性地[[所以你不能在他们的类中加入__getstate__
或类似的]] - 只有在这些对象之间有相互引用的丰富网格时,问题才会出现)。
有没有办法让一个动态创建的类的定义,以便它可以保存到一个文件,然后用作一个普通的类? – tponthieux 2011-06-14 20:27:08