简体   繁体   English

带预抛出钩子的自定义异常?

[英]Custom exception with pre throw hook?

I want an Exception class that "does something" when it is thrown. 我想要一个ExceptionException类。 Dummy example: 虚拟示例:

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

When I throw it using: 当我使用它抛出它:

raise BrowserEatRamError('Chrome is eating all ram')

Chrome should be closed before the exception is thrown. Chrome应该在引发异常之前关闭。 Is there a magic method which can achieve it? 有一种神奇的方法可以实现吗? If not, what is the most elegant way to achieve similar behavior? 如果没有,实现类似行为的最优雅方法是什么?

EDIT: 编辑:

I prefer not to use init because init would be invoked even if the Exception is raised inside a try cache. 我不想使用init,因为即使在try缓存中引发了Exception,也会调用init

No such special method exists. 不存在这种特殊方法。 All of these are documented in the Data model . 所有这些都记录在数据模型中

Assuming you are using the (relatively good) practice of creating and initializing errors and then raising them, ie, 假设您正在使用(相对较好的)做法来创建和初始化错误,然后提出错误,即

raise Error(args)

instead of: 代替:

err = Error(args)
# Somewhere else
raise err

You can simply overload the __intit__ method (Called to initialise it). 您可以简单地重载__intit__方法(调用以对其进行初始化)。

You can also put it in a try / except. 您也可以尝试一下/除外。 If you do this often, you can use a context manager. 如果经常这样做,则可以使用上下文管理器。

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:
    # ...

In both of these ways, if the on_raise method returns True , the exception will stop propogating. 通过这两种方式,如果on_raise方法返回True ,则异常将停止传播。 If it returns False (Or other falsey values, like None ), it will be thrown further. 如果返回False (或其他false值,如None ),它将被进一步抛出。

You can also do this without a context manager, by overwriting sys.excepthook . 您也可以在没有上下文管理器的情况下通过覆盖sys.excepthook来执行此sys.excepthook This is like an __exit__ for the whole program, and is called when the program is about the end, and by default, displays the error. 这就像整个程序的__exit__一样,在程序快要结束时调用,默认情况下显示错误。 Note that this won't work if another program overrides it, and applies in all situations, including other modules, which may cause unexpected behaviour. 请注意,如果另一个程序覆盖它,则该方法将无效,并且在所有情况下都适用,包括其他模块,这可能会导致意外行为。

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

And also, you cannot stop the exception and continue. 而且,您无法停止异常并继续。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM