Pau*_* T. 6 python exception-handling
我想在包含异常名称的异常处理程序中生成一个字符串,以及传递的任何参数......几乎是通过 Traceback 获得的最终输出。
例如,如果raise bar.FnordError("message")被调用,在异常处理程序中,我想生成字符串:"bar.FnordError: message"
我希望它适用于内置异常以及当前和其他模块中的异常。这是我想出的,但它似乎不是很pythonic。
def this_is_lame(err):
if type(err).__module__ in ['__main__', 'builtins']:
return "{}: {}".format(type(err).__name__, err)
else:
return "{}.{}: {}".format(type(err).__module__, type(err).__name__, err)
Run Code Online (Sandbox Code Playgroud)
我已经深入研究了 Python 中的 BaseException C 代码和 Traceback 标准库。我似乎缺少正确的“漂亮”访问器。
有BaseException.__format__记录吗?有逃脱的办法吗?
我在翻译中玩过,没有什么能完全满足我的需求。
import sys
import traceback
import bar
try:
raise bar.FnordError("message")
except Exception as err:
print(type(err))
print(repr(err))
print(type(err).__module__)
print(type(err).__name__)
print(err)
print("this is what I want: '{}'".format(this_is_lame(err)))
print()
try:
raise ValueError("message")
except Exception as err:
print(type(err))
print(repr(err))
print(type(err).__module__)
print(type(err).__name__)
print("this is what I want: '{}'".format(this_is_lame(err)))
Run Code Online (Sandbox Code Playgroud)
它产生:
$ python foo.py
<class 'bar.FnordError'>
FnordError('message',)
bar
FnordError
message
this is what I want: 'bar.FnordError: message'
<class 'ValueError'>
ValueError('message',)
builtins
ValueError
this is what I want: 'ValueError: message'
Run Code Online (Sandbox Code Playgroud)
没有“好的”访问器。Python 本身所做的事情与您在 default 中所做的非常相似sys.excepthook,尽管__main__print as中定义了异常__main__.WhateverException。
如果您想了解 Python 本身是如何做到这一点的,在 Python 2 上,检查发生在 中PyErr_Display,它检查strcmp(modstr, "exceptions"):
moduleName = PyObject_GetAttrString(exception, "__module__");
if (moduleName == NULL)
err = PyFile_WriteString("<unknown>", f);
else {
char* modstr = PyString_AsString(moduleName);
if (modstr && strcmp(modstr, "exceptions"))
{
err = PyFile_WriteString(modstr, f);
err += PyFile_WriteString(".", f);
}
Py_DECREF(moduleName);
}
Run Code Online (Sandbox Code Playgroud)
在 Python 3 上,print_exception检查_PyUnicode_CompareWithId(moduleName, &PyId_builtins).
moduleName = _PyObject_GetAttrId(type, &PyId___module__);
if (moduleName == NULL || !PyUnicode_Check(moduleName))
{
Py_XDECREF(moduleName);
err = PyFile_WriteString("<unknown>", f);
}
else {
if (_PyUnicode_CompareWithId(moduleName, &PyId_builtins) != 0)
{
err = PyFile_WriteObject(moduleName, f, Py_PRINT_RAW);
err += PyFile_WriteString(".", f);
}
Py_DECREF(moduleName);
}
Run Code Online (Sandbox Code Playgroud)