最近在工作的时候,遇到了一个问题,源码简化后如下:
import os
def test():
b = None
e = None
try:
for _ in b:
break
except Exception as e:
raise e
finally:
if e is not None:
os._exit(0)
if __name__ == '__main__':
test()
简单来说,就是遇到异常后,抛出,最后判断异常如果存在,就退出进程
执行后出现错误UnboundLocalError: local variable 'e' referenced before assignment
详情如下:
Traceback (most recent call last):
File "a.py", line 11, in test
raise e
File "a.py", line 8, in test
for _ in b:
TypeError: 'NoneType' object is not iterable
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "a.py", line 18, in <module>
test()
File "a.py", line 13, in test
if e is not None:
UnboundLocalError: local variable 'e' referenced before assignment
很奇怪,本来e已经在开始的时候定义了,为什么最后会说e未被定义就使用了呢?
于是打印出local()
来看下实时的变量
ps:locals()
函数会以字典类型返回当前位置的全部局部变量。
代码如下:
import os
def test():
b = None
e = None
try:
for _ in b:
break
except Exception as e:
print(locals())
print("--------")
raise e
finally:
print(locals())
print("~~~~~~")
if e is not None:
os._exit(0)
if __name__ == '__main__':
test()
结果如下:
{'e': TypeError("'NoneType' object is not iterable",), 'b': None}
--------
{'b': None}
~~~~~~
Traceback (most recent call last):
File "a.py", line 13, in test
raise e
File "a.py", line 8, in test
for _ in b:
TypeError: 'NoneType' object is not iterable
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "a.py", line 22, in <module>
test()
File "a.py", line 17, in test
if e is not None:
UnboundLocalError: local variable 'e' referenced before assignment
由此可以发现,在进入finall模块前,e变量已经被回收了,因此会出现UnboundLocalError: local variable 'e' referenced before assignment
的报错
总结:
except 的异常 会在进入finally前进行回收
如果想完成最初的逻辑可以做出如下修改:
import os
def test():
b = None
exc = None
try:
for _ in b:
break
except Exception as e:
exc = e
raise e
finally:
if exc is not None:
os._exit(0)
if __name__ == '__main__':
test()
不要将异常名与变量名使用同一个,而是定义一个新的变量名,将异常复制给该变量即可
网友评论