python - 为什么我的自定义异常 unpickle 失败

标签 python python-2.7 python-3.x

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)

我已经做了一些谷歌搜索,但很难找到一个很好的答案来解释为什么会发生这种情况,并且不急于开始学习 pickle 序列化格式以逐步解决这个问题:-/

编辑:行为在 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'

最佳答案

我在回答一个与这个问题相关的不同问题,它们有点相同。 reduce 将返回如何重新创建对象,它基于 self.args 中的内容。由于您没有将所有参数传递给 Exception 它会中断。如果您需要能够在不为 a 执行 e.args[0] 和为 b 执行 e.args[1] 等的情况下访问自定义字段,只需创建属性即可。 请注意,Extended 类仍然调用异常 init 而不是 ABError.init

import pickle

class ABError(Exception):
    def __init__(self, a, b):
        super(ABError, self).__init__(a, b)
        
    @property
    def a(self):
        return self.args[0]

    @property
    def b(self):
        return self.args[1]


class ABCDError(ABError):
    def __init__(self, a, b, c, d):
        super(ABError, self).__init__(a, b, c, d)

    @property
    def c(self):
        return self.args[2]

    @property
    def d(self):
        return self.args[3]



err = ABCDError("aaaaa", "bbbbb", "ccccc", "ddddd")

pickled_err = pickle.dumps(err)

original_err = pickle.loads(pickled_err)  # Fails

关于python - 为什么我的自定义异常 unpickle 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41770024/

相关文章:

css - 数据抓取: How to select width from a style tag by using Scrapy CSS?

python - 将 csv 中的值替换为文本并将其写入文件和中心段落

python-3.x - 自更改以来高效的 p​​andas/numpy 函数

python - 如何使用 Python 中的 scikit learn 通过线性回归预测填充 pandas 数据框中的 NA 值?

python - 如何从三重奏 ReceiveStream 一次读取一行?

python - 如何在 PyQt5 InputDialog 中获得更多输入文本?

python - 在python中加载动画

python - 是否有人使用 zeromq 在同一进程中协调多个 Python 解释器?

Python:如何将 GZIP 文件解压缩为磁盘上的未压缩文件?

python - 'if'评估中的Python逻辑错误