我如何腌制肥皂水

我如何腌制肥皂水

本文介绍了我如何腌制肥皂水?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

酸洗是正确的做法吗?我可以使它工作吗?有更好的方法吗?

解决方案

由于您当前收到的错误消息试图告诉您,您正在尝试腌制可腌制的实例(在您现在使用的古老的传统腌制协议中),因为它们的类定义了__slots__而不是__getstate__方法.

但是,即使更改其类也无济于事,因为那样您会遇到 other 问题-您已经正确地将其识别为可能是由于动态生成的类而引起的.所有pickle协议都按名称"对类(和函数)进行序列化,从本质上将它们限制为模块中的顶级名称.而且,绝对地序列化一个实例是否需要序列化该类(如果该类不在周围,您以后怎么可能重新构造该实例呢?

因此,您需要以其他方式保存和重新加载数据,从而打破当前对suds.sudsobject中具体类的直接依赖,转而依赖于可以实际上在访问SOAP服务器时,可以通过此类具体类来实现,或者在从文件中加载数据时,可以通过更简单的自制"类来实现. (毫无疑问,表示实例状态的数据可以表示为dict,因此您可以根据需要将其强制通过pickle,例如通过copy_reg模块,该模块允许您为被强制对象自定义序列化/反序列化协议来进行非侵入式治疗[[因此您无法随意在类中添加__getstate__或类似物]] –仅当此类对象之间存在相互引用的丰富网格时,问题才会出现.

To avoid repeatedly accessing a SOAP server during development, I'm trying to cache the results so I can run the rest of my code without querying the server each time.

With the code below I get a PicklingError: Can't pickle <class suds.sudsobject.AdvertiserSearchResponse at 0x03424060>: it's not found as suds.sudsobject.AdvertiserSearchResponse when I try to pickle a suds result. I guess this is because the classes are dynamically created.

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()

If I drop the -1 protocol version from pickle.dump(result, file, -1), I get a different error:

TypeError: a class that defines __slots__ without defining __getstate__ cannot be pickled

Is pickling the right thing to do? Can I make it work? Is there a better way?

解决方案

As the error message you're currently getting is trying to tell you, you're trying to pickle instances that are not picklable (in the ancient legacy pickle protocol you're now using) because their class defines __slots__ but not a __getstate__ method.

However, even altering their class would not help because then you'd run into the other problem -- which you already correctly identified as being likely due to dynamically generated classes. All pickle protocols serialize classes (and functions) "by name", essentially constraining them to be at top-level names in their modules. And, serializing an instance absolutely does require serializing the class (how else could you possibly reconstruct the instance later if the class was not around?!).

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).

这篇关于我如何腌制肥皂水?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-30 07:26