Python 3异常在未知原因的范围内删除变量 [英] Python 3 exception deletes variable in enclosing scope for unknown reason

查看:160
本文介绍了Python 3异常在未知原因的范围内删除变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码:

  def foo():
e =无
try:
raise异常('我希望你除了我以外我是谁')
除了例外e:
print(e)
print(e)

foo()

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

 我希望你除了我,我是谁。 
我希望你除了我以外我是谁。

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

 追溯(最近的call last):
文件python,第9行,< module>
文件python,第7行,foo
UnboundLocalError:赋值前引用的局部变量'e'

几乎就像在块之外插入 del e 语句一样。这种行为有什么推理吗?如果Python开发人员希望除了块以外具有自己的本地作用域,而不会泄漏到周围的范围内,那么我可以理解它,但为什么必须删除之前分配的外部范围中的变量?

解决方案

引用文档的尝试


当使用作为目标,它将在except子句的末尾被清除。这就好像

 除了E作为N:
foo
/ pre>

被翻译成

 除了E为N:
try:
foo
finally:
del N

这意味着异常必须分配给不同的名称才能在except子句之后引用它。 异常被清除,因为它们附加回溯,它们与堆栈框架形成一个参考循环,保持该帧中的所有本地居住状态,直到下一个垃圾收集发生


这两个PEP包含在这里。


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


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



I have the following code:

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()

In Python 2.7, this runs as expected and prints:

I wish you would except me for who I am.
I wish you would except me for who I am.

However in Python 3.x, the first line is printed, but the second line is not. It seems to delete the variable in the enclosing scope, giving me the following traceback from the last print statement:

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

It is almost as if a del e statement is inserted after the except block. Is there any reasoning for this sort of behavior? I could understand it if the Python developers wanted except blocks to have their own local scope, and not leak into the surrounding scope, but why must it delete a variable in the outer scope that was previously assigned?

解决方案

Quoting the documentation of try,

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

This means the exception must be assigned to a different name to be able to refer to it after the except clause. Exceptions are cleared because with the traceback attached to them, they form a reference cycle with the stack frame, keeping all locals in that frame alive until the next garbage collection occurs.

This is covered in these two PEPs.

  1. PEP 3110 - Catching Exceptions in Python 3000

  2. PEP 344 - Exception Chaining and Embedded Tracebacks

这篇关于Python 3异常在未知原因的范围内删除变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆