Python: 我可以用 def __raise__(self): 重载 raise 语句吗?

5 投票
3 回答
2265 浏览
提问于 2025-04-15 18:45

这是我用raise的异常类:

class SCE(Exception):
    """
    An error while performing SCE functions.
    """
    def __init__(self, value=None):
        """
        Message: A string message or an iterable of strings.
        """
        if value is None:
            self._values = []
        elif isinstance(value, str):
            self._values = [value]
        else:
            self._values = list(value)

    def __raise__(self):
        print('raising')
        if not len(self._values):
            return

    def __str__(self):
        return self.__repr__()

    def __iter__(self):
        return iter(self._values)

    def __repr__(self):
        return repr(self._values)

现在如果我不带值地抛出这个异常,我会得到一个错误追踪信息,后面跟着:

__main__.SCE: []

而不是我预期的结果是:

raising
>>>

我该如何重载raise

3 个回答

0

正如其他人所说,其实并没有一个叫做 __raise__ 的私有方法。虽然没有这个方法,但你可以自己定义一个。比如:

#!/usr/bin/env python3


class MyClass(object):
    def __init__(self, raise_exceptions=False):
        self.raise_exceptions = raise_exceptions

    def __raise__(self, err=None):
        print(err, flush=True)
        if self.raise_exceptions:
            raise err

    def run(self):
        try:
            assert False, 'assertion False'
        except Exception as err:
            self.__raise__(err)


if __name__ == '__main__':
    MyClass(raise_exceptions=False).run()
    MyClass(raise_exceptions=True).run()

下面是输出结果:

$ python3 my_class.py
assertion False
assertion False
Traceback (most recent call last):
  File "my_class.py", line 22, in <module>
    MyClass(raise_exceptions=True).run()
  File "my_class.py", line 17, in run
    self.__raise__(err)
  File "my_class.py", line 11, in __raise__
    raise err
  File "my_class.py", line 15, in run
    assert False, 'assertion False'
AssertionError: assertion False

Process finished with exit code 1
1

没有什么特别的方法叫做 __raise__(至少我从来没听说过,也在Python的文档中找不到)。

你为什么想要这样做呢?我想不出有什么理由让你希望在抛出异常时执行自定义代码(而不是在构造异常时执行,这可以通过 __init__ 方法实现,或者在捕获异常时执行,这可以通过 except 块实现)。你希望这种行为有什么用处,为什么你认为Python会支持它呢?

4

正如其他回答所说,其实没有叫做 __raise__ 的特殊方法。在2004年,comp.lang.python 这个论坛上有人提议添加这样一个方法,但之后似乎没有人继续讨论这个话题。我能想到的唯一能够处理异常抛出的方式,就是修改解释器,或者通过某种方式重写源代码或字节码,在抛出异常的地方插入一个函数调用。

撰写回答