我使用的是 the ordered_set module 的 1.2 版(目前是最新的)链接至 this answer .我一直有一些奇怪的行为,并已将其追溯到:
from ordered_set import OrderedSet
import pickle
os_orig = OrderedSet()
print os_orig # 'OrderedSet'
print os_orig.items # '[]'
pickled = pickle.dumps(os_orig)
loaded = pickle.loads(pickled)
print loaded
这会引发 AttributeError: 'OrderedSet' object has no attribute 'items'
。如果 OrderedSet 不为空,则一切正常。
不幸的是,当谈到 pickle 时,我有点头疼——哪里出了问题?
编辑:我应该补充一点,该模块似乎支持 pickle。来自自述文件:“添加了一个 __getstate__
和 __setstate__
以便它可以被 pickle ”
最佳答案
OrderedSet
的 pickle 支持在集合为空时中断,因为 __getstate__
返回的状态本质上是空的:
>>> OrderedSet().__getstate__()
[]
当再次加载 pickle 时,pickle
模块最终没有调用 __setstate__
,因为 __getstate__
的返回值为空。不调用 __setstate__
意味着永远不会调用 OrderedSet.__init__()
方法并且您有一个损坏的对象。查看__setstate__
documenation :
Note: For new-style classes, if
__getstate__()
returns a false value, the__setstate__()
method will not be called.
空列表是错误值。
作者一定只测试了 pickling 非空 OrderedSet()
实例,效果很好。
您可以通过替换 __getstate__
和 __setstate__
方法来解决此问题:
def __getstate__(self):
return (list(self),)
OrderedSet.__getstate__ = __getstate__
def __setstate__(self, state):
if isinstance(state, tuple):
state = state[0]
self.__init__(state)
OrderedSet.__setstate__ = __setstate__
现在返回一个非空的 1 元素元组,强制 pickle
调用 __setstate__
,即使对于空集也是如此。 __setstate__
仍将接受以前的 pickle 格式,一个列表对象。
我已将其报告为 bug with the project , 由于已解决而关闭。
关于python - 无法 pickle 空的 ordered_set,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24846605/