Python:在异常实例中重写 __str__

标签 python exception string

在引发异常后,我试图覆盖 Python 中 Exception 子类的打印输出,但我没有运气让我的覆盖实际被调用。

def str_override(self):
    """
    Override the output with a fixed string
    """

    return "Override!"

def reraise(exception):
    """
    Re-raise an exception and override its output
    """

    exception.__str__ = types.MethodType(str_override, exception, type(exception))

    # Re-raise and remove ourselves from the stack trace.
    raise exception, None, sys.exc_info()[-1]

def test():
    """
    Should output "Override!" Actually outputs "Bah Humbug"
    """
    try:
        try:
            raise Exception("Bah Humbug")
        except Exception, e:
            reraise(e, "Said Scrooge")
    except Exception, e:
        print e

知道为什么这实际上没有覆盖 str 方法吗?反省实例变量表明该方法实际上已被该方法覆盖,但它就像 Python 只是拒绝通过打印调用它。

我在这里错过了什么?

最佳答案

问题不是 __str__() 没有被覆盖(就像你已经说过的那样),而是 str(e) (通过打印无形地调用)总是等同于e.__str__()。更具体地说,如果我做对了,str()(以及其他特殊方法,例如 repr())将不会查找 str 在实例字典中 - 它只会在类字典中查找它。至少所谓的新型类(Python 3.x IIRC 中仅有的类)就是这种情况。您可以在这里阅读更多相关信息:

http://mail.python.org/pipermail/python-bugs-list/2005-December/031438.html

如果您想更改重新引发的异常的异常错误消息,您可以改为执行以下操作:

def reraise(exception):
    """
    Re-raise an exception and override its output
    """

    exType = type(exception)
    newExType = type(exType.__name__ + "_Override", (exType,), { '__str__': str_override})
    exception.__class__ = newExType

    # Re-raise and remove ourselves from the stack trace.
    raise exception, None, sys.exc_info()[-1]

这将使用 str 覆盖动态派生一个新的异常类,并将异常更改为该类的实例。现在您的代码应该可以工作了。

关于Python:在异常实例中重写 __str__,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5918003/

相关文章:

python - 使用另一个 python 生成器对生成的数字进行排序

string - 从 LUA 中的字符串中删除特殊字符

python - 如何让 python3 命令运行 Python 3.6 而不是 3.5?

python - 你应该导入你在 Python 中使用的所有类吗?

python - 如何在 Sphinx 文档中创建内部超链接

c# - C# switch出现异常后如何继续

kotlin - 如何在 Kotlin 中同时捕获多个异常?

c# - 异常助手不工作

python - 字符串 split() 的身份怪癖

c# - 从字符串转换为 system.drawing.point c#