【发布时间】:2017-01-20 18:19:18
【问题描述】:
import pickle
class ABError(Exception):
def __init__(self, a, b):
super(ABError, self).__init__(a)
self.a = a
self.b = b
class ABCDError(ABError):
def __init__(self, a, b, c, d):
super(ABCDError, self).__init__(a, b)
self.c = c
self.d = d
err = ABCDError("aaaaa", "bbbbb", "ccccc", "ddddd")
pickled_err = pickle.dumps(err)
original_err = pickle.loads(pickled_err) # Fails
我得到以下回溯:
Traceback (most recent call last):
File "pickle_pain.py", line 19, in <module>
original_err = pickle.loads(pickled_err) # Fails
File "/usr/lib/python2.7/pickle.py", line 1388, in loads
return Unpickler(file).load()
File "/usr/lib/python2.7/pickle.py", line 864, in load
dispatch[key](self)
File "/usr/lib/python2.7/pickle.py", line 1139, in load_reduce
value = func(*args)
TypeError: __init__() takes exactly 5 arguments (2 given)
我已经进行了一些谷歌搜索,但很难找到一个很好的答案来解释为什么会发生这种情况,并且并不急于开始学习泡菜序列化格式以逐步完成这个:-/
编辑:python3 中的行为是相同的,尽管错误消息稍微好一点:
Traceback (most recent call last):
File "pickle_pain.py", line 19, in <module>
original_err = pickle.loads(pickled_err) # Fails
TypeError: __init__() missing 3 required positional arguments: 'b', 'c', and 'd'
【问题讨论】:
-
在我看来这是因为
Exception类覆盖了__setstate__? -
只是一个注释,试图为您指明一个有用的方向:显然,在 unpickling 时,系统尝试仅使用 2 个参数调用 init。在 Java 环境中,通常要求有一个默认构造函数,该构造函数将通过反射调用,所有其他字段都通过属性设置器方法设置。要么您需要采用这种方法:将您的 init 更改为在没有其他参数的情况下工作,并在 init 完成后让 unpickling 设置它们,或者您可以找到一种方法pickle 告诉它在 unpickling 时需要提供给 init 的附加参数。
-
您可以进一步简化您的最小示例,因为
ABError的酸洗和解酸会导致相同的错误。 -
谢谢 - 我已经提出了一个更小的版本stackoverflow.com/questions/41808912/…
标签: python python-2.7 python-3.x