不,这不是错误。在Python
3文档中,针对
try/
except语句明确定义了您所遇到的行为。还给出了此行为的原因:
当使用分配了异常后
as target,该异常将在该except子句的末尾清除。好像except E as N: foo被翻译成
except E as N: try: foo finally: del N这意味着必须将异常分配给其他名称,以便在
except子句之后引用它。
清除异常是因为它们具有附加的回溯,它们与堆栈框架形成了一个参考循环,使该框架中的所有局部变量都保持活动状态,直到发生下一个垃圾回收为止 。
在
try/
except块范围之外声明名称无效的原因是因为您
exc在
as子句中使用了该名称。这就是Python删除的名称。
解决方法是在
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
正如Anthony Sottile在评论中指出的,
try/
except代码的反汇编也明确支持文档中的上述声明:
>>> pre = """try: 1/0 text_template = "All fine!"except ZeroDivisionError as exc: text_template = "Got exception: {exc.__class__.__name__}"""">>> from dis import dis>>> dis(pre) 20 SETUP_EXCEPT 16 (to 18) 32 LOAD_ConST 0 (1) 4 LOAD_ConST 1 (0) 6 BINARY_TRUE_DIVIDE 8 POP_TOP 4 10 LOAD_ConST 2 ('All fine!') 12 STORE_NAME 0 (text_template) 14 POP_BLOCK 16 JUMP_FORWARD 38 (to 56) 5 >> 18 DUP_TOP 20 LOAD_NAME 1 (ZeroDivisionError) 22 COMPARE_OP 10 (exception match) 24 POP_JUMP_IF_FALSE 54 26 POP_TOP 28 STORE_NAME 2 (exc) 30 POP_TOP 32 SETUP_FINALLY10 (to 44) 6 34 LOAD_ConST 3 ('Got exception: {exc.__class__.__name__}') 36 STORE_NAME 0 (text_template) 38 POP_BLOCK 40 POP_EXCEPT 42 LOAD_ConST 4 (None) >> 44 LOAD_ConST 4 (None) 46 STORE_NAME 2 (exc) 48 DELETE_NAME 2 (exc) 50 END_FINALLY 52 JUMP_FORWARD 2 (to 56) >> 54 END_FINALLY >> 56 LOAD_ConST 4 (None) 58 RETURN_VALUE
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)