我如何腌制肥皂水?
为了避免在开发过程中重复访问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
腌制是正确的做法吗?我可以使它工作吗?有没有更好的办法?
-
当您当前收到的错误消息试图告诉您时,您正在尝试腌制那些 无法
腌制的实例(在您正在使用的古老的传统腌制协议中),因为它们的类是定义的,__slots__
而不是__getstate__
方法。但是,即使更改其类也无济于事,因为那样的话,您将遇到 另一个 问题-
您已经正确地将其识别为可能是由于动态生成的类所致。所有pickle
协议都按“名称”序列化类(和函数),从本质上将它们限制为模块中的顶级名称。而且,绝对序列化的实例
并不 需要序列化类(怎么回事你能可能以后重建例如,如果类不在身边?!)。因此,您需要以其他方式保存和重新加载数据,从而打破当前对具体类的直接依赖,
suds.sudsobject
而转而依赖于可以同时由此类具体实现实现的接口(形式化或仅由鸭子类型定义)实际上是在访问SOAP服务器时使用的类,或者在从文件加载数据时使用更简单的“自制”类。(毫无疑问,表示实例状态的数据可以表示为dict,因此您可以根据需要将其强制通过pickle,例如通过copy_reg
模块,该模块允许您为被迫处理非对象的对象自定义序列化/反序列化协议-[[因此您无法四处添加__getstate__
或类似的类]]
–仅在此类对象之间存在相互引用的丰富网格时才会出现问题。