我正在使用从这个答案链接到的ordered_set模块的 1.2版本(目前是最新版本).我一直在做一些奇怪的行为,并追溯到这个:
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
Run Code Online (Sandbox Code Playgroud)
哪个加注AttributeError: 'OrderedSet' object has no attribute 'items'.如果OrderedSet不为空,一切都会好起来的.
不幸的是,当谈到泡菜时,我总是在脑子里 - 出了什么问题?
编辑:我应该补充一点,该模块似乎支持泡菜.来自自述文件:"添加了一个__getstate__,__setstate__所以可以腌制"
OrderedSet当set为空时,对于中断的pickle支持,因为返回的状态__getstate__基本上是空的:
>>> OrderedSet().__getstate__()
[]
Run Code Online (Sandbox Code Playgroud)
当再次加载pickle时,pickle模块最终没有调用__setstate__,因为__getstate__返回值为空.不调用__setstate__意味着OrderedSet.__init__()永远不会调用该方法,并且您有一个损坏的对象.查看__setstate__文档:
注意:对于新样式的类,如果
__getstate__()返回false值,__setstate__()则不会调用该方法.
空列表是假值.
作者必须只测试酸洗非空 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__
Run Code Online (Sandbox Code Playgroud)
现在返回一个非空的,1元素的元组,强制甚至pickle调用__setstate__空集.该__setstate__仍将接受以前的咸菜格式,一个列表对象.