如果该名称是,我如何阻止Python删除名称绑定 用于绑定被捕获的异常?什么时候改变了 行为进入Python?
我正在编写代码以在Python 2和Python 3上运行:
exc = None
try:
1/0
text_template = "All fine!"
except ZeroDivisionError as exc:
text_template = "Got exception: {exc.__class__.__name__}"
print(text_template.format(exc=exc))
请注意exc
在异常处理之前显式绑定,因此Python知道它是外部作用域中的名称。
在Python 2.7上,运行正常,exc
名称可以继续使用
format
来电::
Got exception: ZeroDivisionError
很好,这正是我想要的:except
子句绑定名称
我可以在函数的其余部分使用该名称来引用
异常对象。
在Python 3.5上,format
调用失败,因为显然是exc
绑定已删除 ::
Traceback (most recent call last):
File "<stdin>", line 8, in <module>
NameError: name 'exc' is not defined
为什么从外部范围删除exc
绑定?我们的意思是什么
except
之后可靠地保留名称绑定以使用它
条款?
这种变化何时进入Python,它在哪里记录?
我是否应该将此报告为Python 3中的错误?
答案 0 :(得分:6)
不,这不是一个错误。您在Python 3 documentation for the try
/except
statement中明确且明确地定义了您遇到的行为。这种行为的原因也给出了:
使用
clickable
分配异常时,会在void clickable::setFillColor( const Color & color ) { aim.setFillColor( color ); }
子句的末尾清除该异常。这就好像as target
已翻译为
except
这意味着必须将异常分配给其他名称才能在
except E as N: foo
子句后引用它。 异常被清除,因为附加了回溯,它们与堆栈框架形成一个引用循环,保持该框架中的所有本地生存,直到下一次垃圾收集发生。
将except E as N:
try:
foo
finally:
del N
/ except
块范围之外的名称声明为无效的原因是因为您在try
子句中使用了except
。这就是Python删除的名称。
修复是在exc
子句中使用不同的名称将异常绑定到,然后将全局变量分配给不同的异常名称:
as
正如Anthony Sottile在评论中指出的那样,as
/ >>> exc_global = None
>>> try:
1 / 0
text_template = "All fine!"
except ZeroDivisionError as exc:
exc_global = exc
text_template = "Got exception: {exc.__class__.__name__}"
>>> print(text_template.format(exc=exc_global))
Got exception: ZeroDivisionError
代码的反汇编也清楚地支持了文档中的上述陈述:
try