Python 3异常删除封闭范围内的变量,原因不明

Sha*_*ank 11 python exception-handling exception python-3.x

我有以下代码:

def foo():
    e = None
    try:
        raise Exception('I wish you would except me for who I am.')
    except Exception as e:
        print(e)
    print(e)

foo()
Run Code Online (Sandbox Code Playgroud)

在Python 2.7中,它按预期运行并打印:

I wish you would except me for who I am.
I wish you would except me for who I am.
Run Code Online (Sandbox Code Playgroud)

但是在Python 3.x中,第一行是打印的,但第二行不是.它似乎删除了封闭范围中的变量,从最后一个print语句给出了以下回溯:

Traceback (most recent call last):
  File "python", line 9, in <module>
  File "python", line 7, in foo
UnboundLocalError: local variable 'e' referenced before assignment
Run Code Online (Sandbox Code Playgroud)

几乎就像del eexcept块之后插入一个语句一样.这种行为有什么理由吗?我可以理解,如果Python开发人员想要除了块有自己的局部范围,而不是泄漏到周围的范围,但为什么必须删除先前分配的外部范围中的变量?

the*_*eye 14

引用文档try,

使用时分配异常as target时,将在except子句的末尾清除它.这就好像

except E as N:
   foo
Run Code Online (Sandbox Code Playgroud)

被翻译成

except E as N:
    try:
        foo
    finally:
        del N
Run Code Online (Sandbox Code Playgroud)

这意味着必须将异常分配给不同的名称才能在except子句之后引用它.异常被清除,因为附加了回溯,它们与堆栈帧形成一个引用循环,使该帧中的所有本地生存,直到下一次垃圾收集发生.

这包括在这两个PEP中.

  1. PEP 3110 - 捕获Python 3000中的异常

  2. PEP 344 - 异常链接和嵌入式回溯