Python:在异常实例中覆盖__str__ [英] Python: override __str__ in an exception instance

查看:187
本文介绍了Python:在异常实例中覆盖__str__的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在引发异常之后,我试图覆盖Python中Exception子类的打印输出,但我没有运气能够真正调用我的覆盖。

I'm trying to override the printed output from an Exception subclass in Python after the exception has been raised and I'm having no luck getting my override to actually be called.

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只是拒绝通过print调用它。

Any idea why this doesn't actually override the str method? Introspecting the instance variables shows that the method is actually overridden with the method but it's like Python just refuses to call it through print.

我在这里缺少什么?

推荐答案

问题不是不是 __ str __()不会被覆盖(只是就像您已经说过的那样),但是 str(e)(通过打印不可见地调用)总是等同的到 e .__ str __()。更具体地说,如果我做对了,请 str()(以及其他特殊方法,例如 repr()) ,则不会在实例字典中寻找 str -它只会在类字典中寻找它。至少对于所谓的新型类(在Python 3.x IIRC中是唯一的类),情况就是这样。您可以在此处了解更多信息:

The problem is not that __str__() doesn't get overriden (just like you've already said, it does), but rather that str(e) (which invisibly gets called by print) is not always equivalent to e.__str__(). More specifically, if I get it right, str() (and other special methods, such as repr()), won't look for str in the instance dictionary - it would only look for it in the class dictionary. At least that is the case for the so-called new-style classes (which are the only classes in Python 3.x IIRC). You can read more about it here:

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

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

If you want to change the exception error message for a reraised exception, you can do something like this instead:

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 覆盖的新异常类,并将异常更改为该类的实例。现在您的代码应该可以使用了。

This will dynamically derive a new exception class with the str override, and change exception to be an instance of that class. Now your code should work.

这篇关于Python:在异常实例中覆盖__str__的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆