raise with no argument

前端 未结 2 534
孤城傲影
孤城傲影 2021-02-02 10:21

The documentation for the raise statement with no arguments says

If no expressions are present, raise re-raises the last exception that was active in the

2条回答
  •  一整个雨季
    2021-02-02 10:44

    It turns out Python uses a surprising way of building tracebacks. Rather than building the whole stack trace on exception creation (like Java) or when an exception is raised (like I used to think), Python builds up a partial traceback one frame at a time as the exception bubbles up.

    Every time an exception bubbles up to a new stack frame, as well as when an exception is raised with the one-argument form of raise (or the two-argument form, on Python 2), the Python bytecode interpreter loop executes PyTraceback_Here to add a new head to the linked list of traceback objects representing the stack trace. (0-argument raise, and 3-argument raise on Python 2, skip this step.)

    Python maintains a per-thread stack of exceptions (and tracebacks) suspended by except and finally blocks that haven't finished executing. 0-argument raise restores the exception (and traceback) represented by the top entry on this stack, even if the except or finally is in a different function.

    When f executes its raise:

    raise Exception
    

    Python builds a traceback corresponding to just that line:

      File "foo", line 3, in f
        raise Exception
    

    When g executes 0-argument raise, this traceback is restored, but no entry is added for the 0-argument raise line.

    Afterwards, as the exception bubbles up through the rest of the stack, entries for the g() and f() calls are added to the stack trace, resulting in the final stack trace that gets displayed:

    Traceback (most recent call last):
      File "foo", line 10, in 
        f()
      File "foo", line 5, in f
        g()
      File "foo", line 3, in f
        raise Exception
    Exception
    

提交回复
热议问题