kyl*_*yre 29 python serialization exception
为什么下面的自定义Exception类没有使用pickle模块正确序列化/反序列化?
import pickle
class MyException(Exception):
def __init__(self, arg1, arg2):
self.arg1 = arg1
self.arg2 = arg2
super(MyException, self).__init__(arg1)
e = MyException("foo", "bar")
str = pickle.dumps(e)
obj = pickle.loads(str)
Run Code Online (Sandbox Code Playgroud)
此代码抛出以下错误:
Traceback (most recent call last):
File "test.py", line 13, in <module>
obj = pickle.loads(str)
File "/usr/lib/python2.7/pickle.py", line 1382, in loads
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 1133, in load_reduce
value = func(*args)
TypeError: __init__() takes exactly 3 arguments (2 given)
Run Code Online (Sandbox Code Playgroud)
我敢肯定这个问题源于我对如何使课堂泡菜友好缺乏了解.有趣的是,当我的类没有扩展Exception时,不会发生这个问题.
谢谢你的帮助.凯尔
编辑:修复我的超级shx2编辑编辑:清理标题/内容
Sea*_*ean 32
如果您使用两个参数构造错误消息以传递给父Exception类,则当前答案会中断.我认为最好的方法是简单地覆盖__reduce__异常中的方法.该__reduce__方法应返回两项元组.元组中的第一项是你的班级.第二个项是一个元组,包含传递给类的__init__方法的参数.
import pickle
class MyException(Exception):
def __init__(self, arg1, arg2):
self.arg1 = arg1
self.arg2 = arg2
super(MyException, self).__init__('arg1: {}, arg2: {}'.format(arg1, arg2))
def __reduce__(self):
return (MyException, (self.arg1, self.arg2))
original = MyException('foo', 'bar')
print repr(original)
print original.arg1
print original.arg2
reconstituted = pickle.loads(pickle.dumps(original))
print repr(reconstituted)
print reconstituted.arg1
print reconstituted.arg2
Run Code Online (Sandbox Code Playgroud)
有关__reduce__ 此处的更多信息.
Mar*_*ers 27
使arg2可选:
class MyException(Exception):
def __init__(self, arg1, arg2=None):
self.arg1 = arg1
self.arg2 = arg2
super(MyException, self).__init__(arg1)
Run Code Online (Sandbox Code Playgroud)
的基Exception类定义了一个.__reduce__()方法,以使所述延伸(C型)型picklable和该方法仅期望一个参数(该参数是.args); 查看BaseException_reduce()C源代码中的函数.
最简单的解决方法是使额外的参数可选.该__reduce__方法还包括超出的任何其他对象属性.args,.message并且您的实例可以正确地重新创建:
>>> e = MyException('foo', 'bar')
>>> e.__reduce__()
(<class '__main__.MyException'>, ('foo',), {'arg1': 'foo', 'arg2': 'bar'})
>>> pickle.loads(pickle.dumps(e))
MyException('foo',)
>>> e2 = pickle.loads(pickle.dumps(e))
>>> e2.arg1
'foo'
>>> e2.arg2
'bar'
Run Code Online (Sandbox Code Playgroud)
qsc*_*qsc 10
我喜欢Martijn的答案,但我认为更好的方法是将所有参数传递给Exception基类:
class MyException(Exception):
def __init__(self, arg1, arg2):
super(MyException, self).__init__(arg1, arg2)
self.arg1 = arg1
self.arg2 = arg2
Run Code Online (Sandbox Code Playgroud)
基Exception类的__reduce__方法将包括所有的args.通过不使所有额外参数可选,您可以确保正确构造异常.
| 归档时间: |
|
| 查看次数: |
12723 次 |
| 最近记录: |