从坚果壳中的Python
try / except / finally语句,例如:
try: ...guarded clause... except ...expression...: ...exception handler code... finally: ...clean-up code...
等同于嵌套语句:
try: try: ...guarded clause... except ...expression...: ...exception handler code... finally: ...clean-up code...
是否可以写成等同于没有finally
的表单?
是否相当于
try:
...guarded clause...
except ...expression...:
...exception handler code...
...clean-up code...
...clean-up code...
感谢。
答案 0 :(得分:1)
不,您的替代代码与try
/ except
/ finally
版本不完全相同。要了解原因,请考虑如果在示例的...exception handler code...
部分内触发了第二个异常会发生什么。
这是一个显示问题的演示:
try:
print('in try') # guarded code
1/0 # oops, a bug
except ZeroDivisionError:
print('top of except') # exception handling code
name_does_not_exist # oops, the exception handling code is buggy too
print('end of except') # this is a bad place for cleanup code
finally:
print('in finally') # this is a much better place to do cleanup
输出:
in try
top of except
in finally
Traceback (most recent call last):
File "<ipython-input-17-63590fc64963>", line 6, in <module>
name_does_not_exist # oops, the exception handling code is buggy too
NameError: name 'name_does_not_exist' is not defined
请注意,永远不会打印end of except
消息,因为NameError
发生在上一行。如果line是关键的清理代码,那么只有try
和except
的程序将无法运行它。如果您将清理代码放在finally
块中,则无论代码的任何其他部分引发任何异常,都可以保证运行。
答案 1 :(得分:1)
是的,但不是你的方式。
try:
do_stuff()
except OneProblem:
handle_it()
except DifferentProblem:
handle_that()
finally:
cleanup()
相当于
try:
try:
do_stuff()
except OneProblem:
handle_it()
except DifferentProblem:
handle_that()
except:
# Clean up if an unhandled exception happened, then restore the exception.
cleanup()
raise
# Also clean up if we're not propagating an exception.
cleanup()
就清理而言总是发生并且永远不会发生两次,尽管异常链接和追溯等行为可能表现不同。
答案 2 :(得分:0)
这就是我为避免为finally
代码创建函数而不得不从两个不同的地方调用它的目的。
try:
pass
pass
1/0
pass
pass
pass
raise Exception('Success')
except Exception, e:
if e.message != 'Success':
import traceback
print traceback.format_exc()
print 'in finally'
print 'in finally'
print 'in finally'
if e.message != 'Success':
raise
在Linux上的输出:
Traceback (most recent call last):
File "./test_finally.py", line 34, in <module>
1/0
ZeroDivisionError: integer division or modulo by zero
in finally
in finally
in finally
Traceback (most recent call last):
File "./test_finally.py", line 34, in <module>
1/0
ZeroDivisionError: integer division or modulo by zero
shell returned 1