我怎样才能泡泡沫?

时间:2010-01-30 12:46:35

标签: python soap pickle suds

为了避免在开发过程中反复访问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 个答案:

答案 0 :(得分:8)

正如您目前收到的错误信息是试图告诉您,您正在尝试挑选可选择的实例(在您现在使用的古老传统的pickle协议中),因为他们的类定义__slots__但不定义__getstate__方法。

然而,即使改变他们的类也无济于事,因为那时你会遇到其他问题 - 你已经正确地认识到这可能是由于动态生成的类。所有pickle协议都“按名称”序列化类(和函数),基本上将它们限制在模块中的顶级名称。并且,序列化一个绝对的实例需要序列化类(如果该类不存在,你怎么可能在以后重建实例?!)。

因此,您需要以其他方式保存和重新加载数据,打破当前对suds.sudsobject中具体类的直接依赖,转而依赖于接口(正式化或仅通过duck typing定义)当您实际访问SOAP服务器时,可以通过这些具体类实现,或者当您从文件加载数据时,可以通过更简单的“自制”实现。 (表示实例状态的数据无疑可以表示为dict,因此如果您真的需要,可以强制它通过pickle,例如通过copy_reg模块,它允许您自定义对象的序列化/反序列化协议。被迫非侵入地对待[[因此你无法在他们的班级中添加__getstate__等]] - 只有在这些对象之间存在丰富的相互引用网格时才会出现问题。

答案 1 :(得分:2)

您正在挑选类对象本身,而不是类的实例对象。如果重新创建类对象,则无效。但是,只要类对象存在,类的pickling实例就会起作用。