Python 为什么';t finally block在except块内发生异常时返回最新异常?

Python 为什么';t finally block在except块内发生异常时返回最新异常?,python,Python,我已经编写了一段代码,其中我使用traceback返回异常stacktrace。但我忘了导入回溯 文件名-试用版\u main.py from fastapi import FastAPI from pydantic import BaseModel import uvicorn app = FastAPI() class RequestJson(BaseModel): data: str @app.post("/trial", status_code=20

我已经编写了一段代码,其中我使用traceback返回异常stacktrace。但我忘了导入回溯

文件名-试用版\u main.py

from fastapi import FastAPI
from pydantic import BaseModel
import uvicorn


app = FastAPI()

class RequestJson(BaseModel):
    data: str


@app.post("/trial", status_code=200)
async def trial(req:RequestJson):
    try:
        status = "default"
        resp = {
            "status": status,
            "reason": "default reason"
        }
        
        # error point
        a = 10/0
        
        status = "complete"
        reason = "Finished converting from base64 to image"
        
        resp = {
            "status": status,
            "reason": reason
        }
    except Exception as e:
        status = "incomplete"
        resp =  {
            "status": status,
            "reason": traceback.format_exc(),
        }
    finally:
        return resp


if __name__ == '__main__':
    uvicorn.run("trial_main:app", host="0.0.0.0", port=5001, log_level="info")
让我困惑的是,既然找不到回溯模块,为什么代码没有异常退出。而是返回先前设置的默认响应

这是我得到的API响应-

{
    "status": "default",
    "reason": "default reason"
}
这是我运行uvicorn服务器的终端上的输出-

INFO:     Started server process [14744]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:5001 (Press CTRL+C to quit)
INFO:     127.0.0.1:61809 - "POST /trial HTTP/1.1" 200 OK
Api端点-

[POST] http://127.0.0.1:5001/trial
重新创建情景的输入-

{"data": "randomString"}

这里没有什么神秘的事情发生

在try块中,您成功地将值分配给
resp
变量,然后引发异常,执行转到Exception块。在这里,您试图将新值赋给
resp
,但ImportError发生在语句的右侧,因此
resp
仍然包含旧值,该值将在finally块中返回。异常不会进一步传播,因为finally块中有
return
,它只是抑制异常

为了不被fastapi样板文件分散注意力,所有这些都可以用更简单的例子来说明

def always_return():
    """return 1"""
    try:
        res = 1
        raise Exception()
    except Exception:
        res = 1 / 0
    finally:
        return res


def never_return():
    """raises ZeroDivisionError"""

    try:
        res = 1
        raise Exception()
    except Exception:
        res = 1 / 0
    finally:
        print("finally block exists, but no return here")
    return res
>>> print(always_return())
1
>>> print(never_return())
finally block exists, but no return here
ZeroDivisionError: division by zero... traceback