# 这是学习廖雪峰老师python教程的学习笔记
1、概览
我们在运行程序或编写函数时,发生错误后,系统都会返回错误信息。我们可以通过某些机制,让错误信息更加明了
1.1、try
try机制的格式就是 try…except…finally。
try: # try: 运行这段代码,若代码有误,就执行except
print('try...')
r = 10 / 0
print('result:', r)
except ZeroDivisionError as e: # except:捕获指定的错误类型并赋值给变量e。except可以有多个
print('except:', e)
finally: # try 或 except 执行完后,执行finally
print('finally...')
注意:
Python的错误其实也是class,所有的错误类型都继承自BaseException,所以在使用except时需要注意的是,它不但捕获该类型的错误,还把其子类也“一网打尽”。比如:
try:
foo()
except ValueError as e:
print('ValueError')
except UnicodeError as e:
print('UnicodeError')
第二个except永远也捕获不到UnicodeError,因为UnicodeError是ValueError的子类,如果有,也被第一个except给捕获了。
1.2、调用栈
$ python3 err.py
Traceback (most recent call last):
File "err.py", line 11, in <module>
main()
File "err.py", line 9, in main
bar('0')
File "err.py", line 6, in bar
return foo(s) * 2
File "err.py", line 3, in foo
return 10 / int(s)
ZeroDivisionError: division by zero
调用栈就是系统自己返回的错误信息。看调用栈,从上往下看。最后三行指明了错误的根源
1.3、记录错误
如果不捕获错误,可以让Python解释器来打印出错误堆栈,但程序也被结束了。
我们也可以捕获错误,把错误堆栈打印出来,然后分析错误原因,同时,让程序继续执行下去。
Python内置的logging模块可以非常容易地记录错误信息。
import logging
def foo(s):
return 10 / int(s) # 错误根源
def bar(s):
return foo(s) * 2
def main():
try:
bar('0') # main()调用bar(),bar()调用foo()。
except Exception as e:
logging.exception(e)
main()
print('END')
因为有 logging.exception(e)。执行 .py文件后。会继续执行,打印出“END”
1.4、抛出错误
错误是class,捕获一个错误就是捕获到该class的一个实例。所以,错误并不是凭空产生的,而是有意创建并抛出的。抛出的错误既可以是Python的内置函数定义的,也可以是我们自己定义的
1、第一种抛出:
# err_raise.py
class FooError(ValueError): # 定义了一个错误类
pass
def foo(s):
n = int(s)
if n==0:
raise FooError('invalid value: %s' % s) # 抛出自己定义的错误类
return 10 / n
foo('0') # 调用函数
2、第二种抛出:
# err_reraise.py
def foo(s):
n = int(s)
if n==0:
raise ValueError('invalid value: %s' % s) # 抛出ValueError错误
return 10 / n
def bar():
try:
foo('0')
except ValueError as e: # 捕捉错误
print('ValueError!')
raise # raise不带参数,把当前错误原样抛出。因为调用了foo(),所以抛给foo()
bar() # 调用函数
ValueError! # except捕获错误后的print
Traceback (most recent call last): #原样抛出错误,表现形式为协议栈
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in bar
File "<stdin>", line 4, in foo
ValueError: invalid value: 0 # foo()抛出捕获的错误
1.5、错误的转换
在except中raise一个Error,可以把一种类型的错误转化成另一种类型
try:
10 / 0
except ZeroDivisionError:
raise ValueError('input error!')