【Python⼊门】18.错误处理pt与raise的⽤法
笔记更新于2019年12⽉3⽇,
摘要:错误处理;try…except语句;分析错误信息源头;logging记录错误;raise抛出错误
写在前⾯:为了更好的学习python,博主记录下⾃⼰的学习路程。本学习笔记基于,如有侵权,请告知删除。欢迎与博主⼀起学习Pythonヽ( ̄▽ ̄)
⽂章⽬录
错误处理
在程序运⾏过程中,可能会遇到各种错误。如原本要输出整数的却输出了字符串,如因⽤户输⼊信息有误导致后⾯⽆法运⾏,如从⽹络抓取数据时⽹络突然断线导致⽆法抓取等等。这其中有可以修复的bug,也有⽆法预测的错误情况。在Python中,有⼀套内置的错误处理机制,来帮助我们处理错误情况。我们来看看怎么进⾏错误处理。
try
当我们觉得⼀段代码可能会出错时,就可以⽤try语句。如果这段代码出错,则直接跳过后⾯的代码,转到except X语句块,except X是⽤来捕获错误类型X的。最后可加上finally语句,如果有finally语句,则执⾏之。
def fn(a):
try:
print('try')
r = 10 / a
print('result:', r)
except ZeroDivisionError as e:
print('except:', e)
finally:
print('finally')
print('end')
return
先看⼀下有错误的情况,当给fn传⼊0时,会出现除数为0的错误:
>>>fn(0)
try
except: division by zero
finally
end
分析其执⾏过程。执⾏try语句中的“r = 10 / a”发现错误,跳过“print(‘result:’, r)”语句,执⾏except X语句,捕获到错误类型为ZeroDivisionError,则执⾏后⾯紧跟的语句“print(‘except:’, e)”,最后执⾏finally语句。
• except 错误类型
事实上,Python中的错误也是class,所有的错误类型都继承⾃BaseException,Python官⽹给出了。
当可能出现多种错误时,可以加⼊多个except X语句来捕获不同可能产⽣的错误。那如果还出现我们能够捕获之外的错误呢?可以在最后添加“except BaseExcept as e:”,或者直接写"except:"也是可以的。不加的话最终会让Python解释器打印出该错误。
print('try')
r = 10 / a
print('result:', r)
except ZeroDivisionError as e:
print('except:', e)
except ValueError as e:
print('except:', e)
except :
print('unknow except')
finally:
print('finally')
print('end')
return
python的try和except用法>>>fn('a')
try
unknow except
finally
end
当我们尝试传⼊字符串参数时,发⽣错误,但错误类型既不是ZeroDivisionError,也不是ValueError,
所以最终执⾏except :语句。最后执⾏finally语句。若让Python解释器来打印该错误,会发现是TypeError。
• ⽆出现错误情况
此外,我们可以在所有except后加上else,若没有出现错误,则会执⾏else语句。
看⼀下没有错误的情况,我们执⾏fn(2)试试。
def fn(a):
try:
print('try')
r = 10 / a
print('result:', r)
except ZeroDivisionError as e:
print('except:', e)
except ValueError as e:
print('except:', e)
except :
print('unknow except')
else:
print('no errors')
finally:
print('finally')
print('end')
return
>>>fn(2)
try
result: 5.0
no errors
finally
end
由于没有出现错误,所以执⾏try⾥的全部语句,然后跳过except,到else语句。最后执⾏finally语句。
• 多层调⽤
try…except语句可以跨越多层调⽤。⽐如函数a( )调⽤了b( ),b( )调⽤了c( ),c( )出现错误,只要a( )捕获到了就可以处理。
b(s)
except Exception as e:
print('Error', e)
def b(s):
return c(s) + 2
def c(s):
return 9 / s
>>>a(0)
Error division by zero
分析错误
当错误没有被捕获,它就会⼀直往上抛,最后被Python解释器捕获,打印错误信息,然后退出程序,如这个err.py:
# err.py:
def a(s):
b(s)
def b(s):
return c(s) + 2
def c():
return 9 / s
a(0)
执⾏结果:
$ python3 err.py
Traceback (most recent call last):
File "err.py", line 11, in <module>
a(0)
File "err.py", line 3, in a
b(s)
File "err.py", line 6, in b
return c(s) + 2
File "err.py", line 9, in c
return 9 / s
ZeroDivisionError: division by zero
我们从上往下分析这个错误,出关键错误所在。
错误信息第1⾏:告诉我们这是错误的跟踪信息。
Traceback (most recent call last):
错误信息第2~3⾏:表⽰在⽂件err.py的第11⾏代码,模块中的a(0)语句出现错误,但原因是在第3⾏。
File "err.py", line 11, in <module>
a(0)
错误信息第4~5⾏:表⽰在⽂件err.py的第3⾏代码函数a( )中的b(s)语句出现错误,但原因是在第6⾏。
File "err.py", line 3, in a
b(s)
错误信息第6~7⾏:表⽰在⽂件err.py的第6⾏代码函数b( )中的return c(s) + 2语句出现错误,但原因是在第9⾏。
File "err.py", line 6, in b
return c(s) + 2
错误信息第8~9⾏:表⽰在⽂件err.py的第9⾏代码函数c( )中的return 9 / s语句出现错误,下⾯打印出错误原因。
File "err.py", line 9, in c
return 9 / s
错误信息第10⾏:表⽰出现除数为0的错误,属于ZeroDivisionError错误类型,即计算10 / 0 时出错,到错误源头。ZeroDivisionError: division by zero
记录错误
既然可以捕获错误,那么就可以把错误记录下来。
Python内置的logging模块就是⽤来记录错误的。
import logging
def a(s):
try:
b(s)
except Exception as e:
def b(s):
return c(s) + 2
def c(s):
return 9 / s
a(0)
print('end')
执⾏结果:
ERROR:root:division by zero
Traceback (most recent call last):
File "error.py", line 6, in a
b(s)
File "error.py", line 11, in b
return c(s) + 2
File "error.py", line 13, in c
return 9 / s
ZeroDivisionError: division by zero
end
最后的print(‘end’)语句是有执⾏的,可见在有logging的情况下,遇到错误时,程序会打印错误信息后会继续执⾏,最后正常退出。⽽没有logging的情况下,遇到错误时会中途退出。
通过配置,logging还可以把错误记录到⽇志⽂件⾥,⽅便事后排查。
抛出错误
既然错误是class,那我们也可以⾃⼰定义⼀个错误类型,遇到⾃认为是错误情况时,抛出⼀个错误实例。⽤raise语句可以将⼀个错误实例抛出。
def fn(s):
n = s
if n == 0:
raise MyError('invalid value: %s' % s)
return 9 / n
fn(0)
执⾏结果:
Traceback (most recent call last):
File "myerror.py", line 11, in <module>
fn(0)
File "myerror.py", line 8, in fn
raise MyError('invalid value: %s' % s)
__main__.MyError: invalid value: 0
错误信息最后跟踪到⾃⼰定义的错误。
只有在必要的时候才⾃⼰定义错误,⼀般情况下还是⽤Python内置的错误类型,也是可以⽤raise语句抛出的。
虽然raise和try语句都有打印错误信息的作⽤,但两者的⽤途并不冲突,raise语句负责抛出错误信息,⽽try语句负责检查是否有错误信息并捕获信息。若没有try语句,那么错误信息就要让python的解释器来处理。
def fn(s):
n = int(s)
if n==0:
raise ValueError('invalid value: %s' % s)
return 10 / n
def a():
try:
fn('0')
except ValueError as e:
print('ValueError!')
raise
a()
raise语句也可以不带参数,此时按原错误信息抛出。此外,在except中raise⼀个Error,还可以把⼀种类型的错误转化成另⼀种类型,像这样:
try:
10 / 0
except ZeroDivisionError:
raise ValueError('input error!')
补充
1.split( )函数过指定分隔符对字符串进⾏切⽚。传⼊参数有两个,第⼀个为分隔符,默认为所有的空字符,包括空格、换⾏(\n)、制表符(\t)等;第⼆个为分割次数,默认全部分割。
2.虽然程序可以主动抛出错误让⽤户知道,但我们要在程序⽂档中写清楚可能出现的错误以及错误产⽣的原因和解决办法等。
以上就是本节的全部内容,感谢你的阅读。
下⼀节内容:19.Python中的调试与测试
有任何问题与想法,欢迎评论与吐槽。
和博主⼀起学习Python吧( ̄▽ ̄)~*

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。