Python:pickle派生的str对象

时间:2013-01-09 23:57:51

标签: python string cpython pickle

运行:

import pickle

class Foo(str):
    def __new__(cls, s, bar):
        self = super(Foo, cls).__new__(cls, s)
        self.bar = bar
        return self

with open('foo.pkl', 'wb') as w:
    x = pickle.dump(Foo('', 1), w, pickle.HIGHEST_PROTOCOL)

with open('foo.pkl', 'rb') as w:
    x = pickle.load(w)

此例外的结果:

Traceback (most recent call last):
  File "pkl.py", line 13, in <module>
    x = pickle.load(w)
  File "/usr/lib/python2.7/pickle.py", line 1378, in load
    return Unpickler(file).load()
  File "/usr/lib/python2.7/pickle.py", line 858, in load
    dispatch[key](self)
  File "/usr/lib/python2.7/pickle.py", line 1083, in load_newobj
    obj = cls.__new__(cls, *args)
TypeError: __new__() takes exactly 3 arguments (2 given)

如果我删除了pickle.HIGHEST_PROTOCOL,它会有效,但如果可能的话,我宁愿使用新协议。

我没有得到泡菜协议说明。谁能帮我吗?魔术方法必须有某种方式......

1 个答案:

答案 0 :(得分:5)

这不适用于HIGHEST_PROTOCOL,因为较旧的协议不会将__new__构造函数用于未分类的对象。

但基本的是,在向str添加新参数时,您正在使用__new__的序列化方法。 pickle模块或内置str类型对此有任何了解,它将导致显示错误。

要修复它,您应该定义__getnewargs__方法并返回(self.__class__, self.bar),这应该足以让它再次工作。

可以找到pickle模块使用的特殊方法的文档here