等价于 try / except / finally 语句
Equivalence to a try / except / finally statement
来自 Python 简而言之
A try / except / finally statement, such as:
try:
...guarded clause...
except ...expression...:
...exception handler code...
finally:
...clean-up code...
is equivalent to the nested statement:
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...
谢谢。
不,您的替代代码并不完全等同于 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
块中,则无论代码的任何其他部分是否引发任何异常,都可以保证 运行。
- 因为它就是这样定义的。因为以这种方式定义它是有用的和标准的,而且因为没有其他有用的方式来定义它。
是的,但不是你做的那样。
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()
就清理而言,总是会发生并且不会发生两次,尽管异常链接和回溯之类的行为可能会有所不同。
以下是我用来避免为 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
来自 Python 简而言之
A try / except / finally statement, such as:
try: ...guarded clause... except ...expression...: ...exception handler code... finally: ...clean-up code...
is equivalent to the nested statement:
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...
谢谢。
不,您的替代代码并不完全等同于 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
块中,则无论代码的任何其他部分是否引发任何异常,都可以保证 运行。
- 因为它就是这样定义的。因为以这种方式定义它是有用的和标准的,而且因为没有其他有用的方式来定义它。
是的,但不是你做的那样。
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()
就清理而言,总是会发生并且不会发生两次,尽管异常链接和回溯之类的行为可能会有所不同。
以下是我用来避免为 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