9

为了避免在开发过程中重复访问 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

酸洗是正确的做法吗?我可以让它工作吗?有没有更好的办法?

4

2 回答 2

9

正如您当前收到的错误消息试图告诉您的那样,您正在尝试腌制不可腌制的实例(在您现在使用的古老的遗留腌制协议中),因为它们的类定义__slots__但不是__getstate__方法。

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

So you'll need to save and reload your data in some other way, breaking your current direct dependence on concrete classes in suds.sudsobject in favor of depending on an interface (either formalized or just defined by duck typing) that can be implemented both by such concrete classes when you are in fact accessing the SOAP server, or simpler "homemade" ones when you're loading the data from a file. (The data representing instance state can no doubt be represented as a dict, so you can force it through pickle if you really want, e.g. via the copy_reg module which allows you to customize serialize/deserialize protocols for objects that you're forced to treat non-invasively [[so you can't go around adding __getstate__ or the like to their classes]] -- the problem will come only if there's a rich mesh of mutual references among such objects).

于 2010-01-30T17:45:01.230 回答
3

您正在腌制类对象本身,而不是类的实例对象。如果重新创建类对象,这将不起作用。但是,只要类对象存在,类的酸洗实例就可以工作。

于 2010-01-30T13:11:44.963 回答