我最近遇到了插槽和泡菜的特殊问题。我已将问题隔离到以下设置:
import operator
import pickle
class BinaryOperator(object):
__slots__ = ("a", "b")
operator = None
def __init__(self, a=None, b=None):
self.a = a
self.b = b
def execute(self):
return self.operator(self.a, self.b)
class Add(BinaryOperator):
__slots__ = ()
operator = operator.add
if __name__ == "__main__":
# This works as intended
add = Add(1, 1)
assert add.execute() == 2
# This fails:
# Traceback (most recent call last):
# File "slotstest.py", line 26, in <module>
# assert pickle_add.execute() == 2
# File "slotstest.py", line 14, in execute
# return self.operator(self.a, self.b)
# AttributeError: a
pickle_add = pickle.loads(pickle.dumps(add))
assert pickle_add.execute() == 2
# Workaround using pickling version
pickle_add = pickle.loads(pickle.dumps(add, -1))
assert pickle_add.execute() == 2
这个问题不会发生在Python 3上,我认为这与新版本的pickle协议有关。
如何使Add与默认的Python 2.7版本的pickle兼容?
答案 0 :(得分:1)
如果您需要支持古老的pickle协议,请在您的类中添加特殊方法来设置和恢复实例状态,例如
def __getstate__(self):
return self.a, self.b
def __setstate__(self, state):
self.a, self.b = state