Python在运行中发生错误怎么正确处理方法,案例详解!

在程序运行的过程当中,若是发生了错误,能够事先约定返回一个错误代码,这样,就能够知道是否有错,以及出错的缘由。在操做系统提供的调用中,返回错误码很是常见。好比打开文件的函数open(),成功时返回文件描述符(就是一个整数),出错时返回-1。
Python教程
用错误码来表示是否出错十分不便,由于函数自己应该返回的正常结果和错误码混在一块儿,形成调用者必须用大量的代码来判断是否出错:html

def foo():
r = some_function()
if r==(-1):
return (-1)
# do something
return rpython

def bar():
r = foo()
if r==(-1):
print(‘Error’)
else:
pass
若是你以为看这些理论知识乏味不够形象,能够进他们的Python技术扣扣裙【278136312】 裙公告里面有讲的很是详细的完整版Python入门到实战+笔记+源码+做业视频教程免费下载,生动的讲解可让你思路更清晰,遇到问题里面有大佬解答,
一旦出错,还要一级一级上报,直到某个函数能够处理该错误(好比,给用户输出一个错误信息)。函数

因此高级语言一般都内置了一套try…except…finally…的错误处理机制,Python也不例外。学习

try
让咱们用一个例子来看看try的机制:操作系统

try:
print(‘try…’)
r = 10 / 0
print(‘result:’, r)
except ZeroDivisionError as e:
print(‘except:’, e)
finally:
print(‘finally…’)
print(‘END’)
当咱们认为某些代码可能会出错时,就能够用try来运行这段代码,若是执行出错,则后续代码不会继续执行,而是直接跳转至错误处理代码,即except语句块,执行完except后,若是有finally语句块,则执行finally语句块,至此,执行完毕。code

上面的代码在计算10 / 0时会产生一个除法运算错误:视频

try…
except: division by zero
finally…
END
从输出能够看到,当错误发生时,后续语句print(‘result:’, r)不会被执行,except因为捕获到ZeroDivisionError,所以被执行。最后,finally语句被执行。而后,程序继续按照流程往下走。htm

若是把除数0改为2,则执行结果以下:blog

try…
result: 5
finally…
END
因为没有错误发生,因此except语句块不会被执行,可是finally若是有,则必定会被执行(能够没有finally语句)。继承

你还能够猜想,错误应该有不少种类,若是发生了不一样类型的错误,应该由不一样的except语句块处理。没错,能够有多个except来捕获不一样类型的错误:

try:
print(‘try…’)
r = 10 / int(‘a’)
print(‘result:’, r)
except ValueError as e:
print(‘ValueError:’, e)
except ZeroDivisionError as e:
print(‘ZeroDivisionError:’, e)
finally:
print(‘finally…’)
print(‘END’)
ps:另外不少人在学习Python的过程当中,每每由于没有好的教程或者没人指导从而致使本身容易放弃,为此我建了个Python交流.裙 :一久武其而而流一思(数字的谐音)转换下能够找到了,里面有最新Python教程项目可拿,不懂的问题多跟里面的人交流,都会解决哦!
int()函数可能会抛出ValueError,因此咱们用一个except捕获ValueError,用另外一个except捕获ZeroDivisionError。

此外,若是没有错误发生,能够在except语句块后面加一个else,当没有错误发生时,会自动执行else语句:

try:
print(‘try…’)
r = 10 / int(‘2’)
print(‘result:’, r)
except ValueError as e:
print(‘ValueError:’, e)
except ZeroDivisionError as e:
print(‘ZeroDivisionError:’, e)
else:
print(‘no error!’)
finally:
print(‘finally…’)
print(‘END’)
Python的错误其实也是class,全部的错误类型都继承自BaseException,因此在使用except时须要注意的是,它不但捕获该类型的错误,还把其子类也“一网打尽”。好比:

try:
foo()
except ValueError as e:
print(‘ValueError’)
except UnicodeError as e:
print(‘UnicodeError’)
第二个except永远也捕获不到UnicodeError,由于UnicodeError是ValueError的子类,若是有,也被第一个except给捕获了。

Python全部的错误都是从BaseException类派生的,常见的错误类型和继承关系看这里:

https://docs.python.org/3/library/exceptions.html#exception-hierarchy

使用try…except捕获错误还有一个巨大的好处,就是能够跨越多层调用,好比函数main()调用foo(),foo()调用bar(),结果bar()出错了,这时,只要main()捕获到了,就能够处理:

def foo(s):
return 10 / int(s)

def bar(s):
return foo(s) * 2

def main():
try:
bar(‘0’)
except Exception as e:
print(‘Error:’, e)
finally:
print(‘finally…’)
也就是说,不须要在每一个可能出错的地方去捕获错误,只要在合适的层次去捕获错误就能够了。这样一来,就大大减小了写try…except…finally的麻烦。

调用栈
若是错误没有被捕获,它就会一直往上抛,最后被Python解释器捕获,打印一个错误信息,而后程序退出。来看看err.py:

err.py:

def foo(s):
return 10 / int(s)

def bar(s):
return foo(s) * 2

def main():
bar(‘0’)

main()
执行,结果以下:

$ python3 err.py
Traceback (most recent call last):
File “err.py”, line 11, in 
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行:

Traceback (most recent call last):
告诉咱们这是错误的跟踪信息。

第2~3行:

File “err.py”, line 11, in 
main()
调用main()出错了,在代码文件err.py的第11行代码,但缘由是第9行:

File “err.py”, line 9, in main
bar(‘0’)
调用bar(‘0’)出错了,在代码文件err.py的第9行代码,但缘由是第6行:

File “err.py”, line 6, in bar
return foo(s) * 2
缘由是return foo(s) * 2这个语句出错了,但这还不是最终缘由,继续往下看:

File “err.py”, line 3, in foo
return 10 / int(s)
缘由是return 10 / int(s)这个语句出错了,这是错误产生的源头,由于下面打印了:

ZeroDivisionError: integer division or modulo by zero根据错误类型ZeroDivisionError,咱们判断,int(s)自己并无出错,可是int(s)返回0,在计算10 / 0时出错,至此,找到错误源头。----PS;另外不少人在学习Python的过程当中,每每由于没有好的教程或者没人指导从而致使本身容易放弃,为此我建了个Python交流.裙 :一久武其而而流一思(数字的谐音)转换下能够找到了,里面有最新Python教程项目可拿,不懂的问题多跟里面的人交流,都会解决哦!

相关文章
相关标签/搜索