try...except...finally
实例(finally语句一定会执行):
>>> try:
print('try...')
r = 10 / 0
print('result: ', r)
except ZeroDivisionError as e:
print('except: ', e)
finally:
print('finally...')
try...
except: division by zero
finally...
上例只处理了一种错误,利用不同的except语句可以处理不同类型的错误。
此外,如果没有错误发生,可以在except语句后加else语句,当没有错误发生时,会自动执行else语句,例如:
>>> try:
print('try...')
r = 10 / int('2')
print('result: ',r)
except ValueError as e:
print('ValueError: ', e)
else:
print('no error!')
finally:
print('finally...')
try...
result: 5.0
no error!
finally...
python中的所有错误也属于class,所有的错误都是继承于BaseException,故在使用except语句时,捕获此类错误时也将其子类全部捕获。
记录错误
使用logging模块可以用于记录错误,例如:
import logging
def foo(s):
return 10 / int(s)
def bar(s):
return foo(s) * 2
def main():
try:
bar('0')
except Exception as e:
logging.exception(e)
main()
print('END')
ERROR:root:division by zero
Traceback (most recent call last):
File "D:/Users/Administrator/AppData/Local/Programs/Python/Python36-32/MyPythonScripts/err_logging.py", line 10, in main
bar('0')
File "D:/Users/Administrator/AppData/Local/Programs/Python/Python36-32/MyPythonScripts/err_logging.py", line 6, in bar
return foo(s) * 2
File "D:/Users/Administrator/AppData/Local/Programs/Python/Python36-32/MyPythonScripts/err_logging.py", line 3, in foo
return 10 / int(s)
ZeroDivisionError: division by zero
END
程序出错,但程序打印完错误信息后继续执行,并正常退出。
抛出错误
由于错误属于class,捕获一个错误就相当于捕获到该class中的一个实例。
如需要抛出错误,首先要根据需求,定义一个错误的class,选择好继承关系,然后用raise语句抛出一个错误的实例,例如:
>>> class FooError(ValueError):
pass
>>> def foo(s):
n = int(s)
if n == 0:
raise FooError('invalid value: %s' % s)
return 10 / n
>>> foo('0')
Traceback (most recent call last):
File "<pyshell#47>", line 1, in <module>
foo('0')
File "<pyshell#46>", line 4, in foo
raise FooError('invalid value: %s' % s)
FooError: invalid value: 0
只有在必要的情况下才去定义一个错误类型。若可以选择python内置的错误类型,尽量使用内置错误类型。
raise如果不带有参数时,则将当前错误原样抛出,例如:
>>> try:
10 / 0
except ZeroDivisionError:
raise
Traceback (most recent call last):
File "<pyshell#112>", line 2, in <module>
10 / 0
ZeroDivisionError: division by zero
若在except中raise一个error,可以将一种错误类型转化为另一种,例如:
>>> try:
10 / 0
except ZeroDivisionError:
raise ValueError('error input!')
Traceback (most recent call last):
File "<pyshell#70>", line 2, in <module>
10 / 0
ZeroDivisionError: division by zero
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<pyshell#70>", line 4, in <module>
raise ValueError('error input!')
ValueError: error input!
错误类型的转化绝不能在毫不相干的错误类型之间转换。