Python 变量范围 - 如果在内部异常中使用,则外部异常变量未定义

Python variable scope - outer exception variable undefined if used in inner exception

有人可以帮助我了解这里发生的事情吗?我对变量范围在 python 中的工作方式有一些了解。
当这段代码 运行s 时,我得到一个错误:

rec = True

    try:
        print("outer try")
        raise Exception("outer exception")
    except Exception as msg:
        try:
            rec = True
            print("inner try")
            raise Exception("inner exception")
        except Exception as msg:
            rec = False
            print(str(msg))
        
        if rec == False:
            print(str(msg))

错误输出:
outer try
inner try
inner exception

---------------------------------------------------------------------------
Exception Traceback (most recent call last)
<ipython-input-2-6ce9b26112ed> in <module>
      5     print("outer try")
----> 6     raise Exception("outer exception")
      7 except Exception as msg:

Exception: outer exception

During handling of the above exception, another exception occurred:

NameError Traceback (most recent call last)
<ipython-input-2-6ce9b26112ed> in <module>
     15 
     16     if rec == False:
---> 17         print(str(msg))

NameError: name 'msg' is not defined

我的理解是,当调用并完成内部异常时,"msg" 变量未设置或从内存中删除。

现在,当我 运行 这段代码时,它 运行 成功了:
rec = True

try:
    print("outer try")
    raise Exception("outer exception")
except Exception as outer_msg:
    try:
        rec = True
        print("inner try")
        raise Exception("inner exception")
    except Exception as msg:
        rec = False
        print(str(msg))
    
    if rec == False:
        print(str(outer_msg))

输出:

outer try
inner try
inner exception
outer exception

此错误与“变量作用域”或“闭包”有关吗?如果有人 link 在 python 中对此有详细的解释,请帮忙。

块开始

except Exception as msg:

在块的开头创建 msg 变量,并在块的末尾删除它。已经存在的msg变量在同一作用域内,同名,覆盖后删除。

如果要跟踪两个异常,则需要为两个异常使用不同的名称,因为它们在同一范围内。

请参阅 https://docs.python.org/3/reference/compound_stmts.html#the-try-statement 内容:

When an exception has been assigned using as target, it is cleared at the end of the except clause. This is as if

except E as N:
    foo

was translated to

except E as N:
    try:
        foo
    finally:
        del N