预抛异常的自定义异常?

时间:2017-06-04 16:50:33

标签: python exception

我想要一个Exception课程"做某事"当它被抛出。 虚拟的例子:

class BrowserEatRamError(Exception):
    def __raise__(self):
        os.system('Killall -9 chrome')
        super(BrowserEatRamError, self).__raise__()

当我使用它抛出它时:

raise BrowserEatRamError('Chrome is eating all ram')

在抛出异常之前应关闭Chrome。有没有可以实现它的神奇方法?如果不是,实现类似行为的最优雅方式是什么?

编辑:

我不想使用 init ,因为即使在try缓存中引发Exception,也会调用 init

1 个答案:

答案 0 :(得分:2)

不存在这种特殊方法。所有这些都记录在Data model

假设您正在使用(相对较好的)创建和初始化错误然后提高它们的做法,即

raise Error(args)

而不是:

err = Error(args)
# Somewhere else
raise err

您可以简单地重载__intit__方法(调用以初始化它)。

你也可以把它放在try / except中。如果经常这样做,可以使用上下文管理器。

try:
     # ...
except Exception as e:
    # Reraise if the exception doesn't have a `.on_raise()` method
    # Or that method returns a falsey value.
    if not hasattr(e, 'on_raise') or not e.on_raise():
        raise
class CustomRaiseAction(object):
    def __enter__(self):
        return
    def __exit__(exception_type, exception_value, traceback):
        if hasattr(exception_type, 'on_raise'):
            return exception_type.on_raise(exception_value)
custom_raise_action = CustomRaiseAction()

with custom_raise_action:
    # ...

在这两种方式中,如果on_raise方法返回True,则异常将停止传播。如果它返回False(或其他虚假值,如None),则会进一步抛出。

您也可以通过覆盖sys.excepthook在没有上下文管理器的情况下执行此操作。这类似于整个程序的__exit__,并在程序即将结束时调用,默认情况下显示错误。请注意,如果其他程序覆盖它,这将无效,并适用于所有情况,包括其他模块,这可能会导致意外行为。

import sys

old_excepthook = sys.excepthook
def new_excepthook(exception_type, exception_value, traceback):
    if hasattr(exception_type, 'on_raise'):
        exception_type.on_raise(exception_value)
    old_excepthook(exception_type, exception_value, traceback)
sys.excepthook = new_excepthook

而且,你无法阻止异常并继续。