Python 如何序列化异常

Python 如何序列化异常,python,json,python-2.7,exception,serialization,Python,Json,Python 2.7,Exception,Serialization,当我尝试使用json.dump序列化异常时,会出现如下错误 TypeError: IOError('socket error', error(61, 'Connection refused')) is not JSON serializable 及 异常的\uuuuu dict\uuuu字段是{}(这就是为什么对我没有帮助:这里的答案假设\uuuu dict\uuuu包含所有必要的信息,它们还假设我可以控制要序列化的类) 是否有比保存str(exn)更智能的方法 我更喜欢人类可读的文本表示(而

当我尝试使用
json.dump
序列化异常时,会出现如下错误

TypeError: IOError('socket error', error(61, 'Connection refused')) is not JSON serializable

异常的
\uuuuu dict\uuuu
字段是
{}
(这就是为什么对我没有帮助:这里的答案假设
\uuuu dict\uuuu
包含所有必要的信息,它们还假设我可以控制要序列化的类)

是否有比保存
str(exn)
更智能的方法

我更喜欢人类可读的文本表示(而不是
pickle

注:以下是我的想法:

def exception_as_dict(ex):
    return dict(type=ex.__class__.__name__,
                errno=ex.errno, message=ex.message,
                strerror=exception_as_dict(ex.strerror)
                if isinstance(ex.strerror,Exception) else ex.strerror)

json.dumps(exception_as_dict(err),indent=2)
{
  "errno": "socket error", 
  "type": "IOError", 
  "strerror": {
    "errno": 61, 
    "type": "error", 
    "strerror": "Connection refused"
  }
}

异常不能被pickle(默认情况下),您有两个选项:

  • 使用Python的内置格式_exc()并序列化格式化字符串

  • 使用

  • 使用后者,您可以传递包装的异常,也可以稍后重新验证它们

    import tblib.pickling_support
    tblib.pickling_support.install()
    import pickle, sys 
    
    def inner_0():
        raise Exception('fail')
    
    def inner_1():
        inner_0()
    
    def inner_2():
        inner_1()
    
    try:
        inner_2()
    except:
        s1 = pickle.dumps(sys.exc_info())
    

    您可以将
    exc\u info
    traceback
    一起使用,如下所示:

    import traceback
    import sys
    try:
        raise KeyError('aaa!!!')
    except Exception as e:
        exc_info = sys.exc_info()
        print(''.join(traceback.format_exception(*exc_info)))
    

    您可以捕获异常对象并对其进行pickle吗?您可以将pickle数据作为二进制有效负载传递到JSON对象中。@cᴏʟᴅsᴘᴇᴇᴅ: 我更喜欢人类可读的文本表示。你的评论表明答案是“不”。谢谢,你没说清楚。似乎您需要某种远程通信执行的方式。无论如何,您必须寻找一些第三方库,或者编写您自己的自定义解析器来解构或构造JSON中的对象。可能重复的@Leon:不是真正的重复:
    \uuu dict\uuu
    异常中是无用的。
    
    import traceback
    import sys
    try:
        raise KeyError('aaa!!!')
    except Exception as e:
        exc_info = sys.exc_info()
        print(''.join(traceback.format_exception(*exc_info)))