Python之异常
上一周小苏给大家介绍了测试代码,通过测试代码我们可以验证自己的程序是不是按照我们的意愿来完成任务,是一个很常用的工具,虽然测试能够检查程序的功能,但是当自己的代码出现某些特殊错误时,测试代码只能确定程序无法实现功能却不能指出程序是哪里出现问题应该怎样解决,所以这周小苏决定给大家介绍一下python里的异常。异常是python创建的特殊对象,用于管理程序运行时出现的错误,学习处理异常可以帮我们应对文件不存在以及其它可能导致程序崩溃的情况。这些都可以使我们的程序在面对错误时变得更加成熟--无论这些错误数据是源自无意识的错误,还是破坏程序的恶意企图。
每当发生让python不知所措的错误时,他都会创建一个异常对象,如果我们编写了处理异常的代码,程序将继续运行,但是如果我们未对程序做任何处理的话,程序将会停止运行,并且显示一个traceback,其中包含有关异常的报告。异常是使用try-except代码块处理的,try-except代码块让python执行指定的操作,同时告诉他发生异常应该怎么办,从而使我们不受traceb
ack迷惑。接下来我们就一起来看看python的异常吧!
处理ZeroDivisionError异常
下面我们来看一种python里异常引发简单的错误,我们让python实现一个数除以零的运算试一试:
division.py
print(10/0)
显然这样写是错误的,因此我们会看到一条traceback:
Traceback (most recent call last):
File "E:/codewares_python/division.py", line 1, in <module>
print(10/0)
ZeroDivisionError: division by zero
上述显示的ZeroDivisionError就是一个异常对象,由于python无法完成我们的指令,所以会显示一条traceback,接下来我们就告诉python,以后遇到这种情况应该怎么办。
使用try-except代码块
当我们感觉自己的程序出现了问题的时候,我们可以编写一个try-except代码块来处理可能引发的异常,如处理ZeroDivisionError异常的try-except代码块如下所示:
try:
print(10/0)
except ZeroDivisionError:
print("You can't divide by zero !")
如果try代码块中的代码没有问题,python将直接跳过except代码块,如果发生了错误,python将跳到except代码块(指出try中错误的异常信息)并执行其中的代码。上述代码执行结果如下:
You can't divide by zero !
如果程序后面还有其它代码,python将继续执行。
使用异常避免程序崩溃
在程序发生错误时,如果程序还有工作未完成,此时妥善处理错误就十分重要。尤其是在程序需要用户输入的情况下,如果能够处理用户的无效输入,然后提示用户输入有效的数据,这样就可以避免程序崩溃。我们来创建一个只执行除法的简易计算器感受一下:
division.py
print("I am a calculator, please give me two numbers, i will divide them.")
print("Enter 'q' to quit.")
while True:
first_number = input("\nFirst number:")
if(first_number == 'q'):
break
second_number = input("Second number:")
if(second_number == 'q'):
break
answer = int(first_number) / int(second_number)
print(answer)
这个程序实现两个数相除,没有对用户的输入采取任何措施,因此如果第二个数为0时,程序将发生错误如下所示:
I am a calculator, please give me two numbers, i will divide them.
Enter 'q' to quit.
First number:3
Second number:0
Traceback (most recent call last):
File "E:/codewares_python/division.py", line 11, in <module>
answer = int(first_number) / int(second_number)
ZeroDivisionError: division by zero
我们可以看到,如果不对用户的输入进行任何处理,程序很容易就会崩溃,下面我们看一下python是如何解决这个问题的。
else代码块
当我们想要让程序在抓取到异常后还要继续完成任务时就可以使用else代码块,它依赖于try代码块成功执行,如下所示:
print("I am a calculator, please give me two numbers, i will divide them.")
print("Enter 'q' to quit.")
while True:
first_number = input("\nFirst number:")
if(first_number == 'q'):
break
second_number = input("Second number:")
try:
answer = int(first_number) / int(second_number)
except ZeroDivisionError:
print("You can't divide by 0 !")
else:
print(answer)
上述代码中,当try成功运行时,我们就使用else来输出结果,如果发生异常,就打印出一条提示信息,如下所示:
I am a calculator, please give me two numbers, i will divide them.
Enter 'q' to quit.
First number:3
Second number:0
You can't divide by 0 !
First number:6
Second number:3
2.0
First number:q
try-except-else代码块执行过程大概是:python尝试执行try中的代码块,只有可能引起异常的代码才会放在try代码块中,有一些代码需要try代码块成功运行之后才执行,这些代码就放在else代码块中,except负责告诉python在try代码块中出现了指定的异常。
pass语句
有的时候我们会希望自己的程序在发生异常的时候一声不吭,就像什么都没有发生一样继续运行,此时不需要更改try语句,只需要在except代码块中使用pass语句,让它来告诉python什么都不要做,就像是之前我们学C语言的时候,再循环里使用分号表示一个空语句;pass语句也充当占位符,它提醒我们在程序的某个地方什么都没有做,并且以后可能要在这个地方做些什么。具体使用方法如下:
try:
pass
#占位
except ZeroDivisionError:
pass
#没有任何提示信息
else:
pass
#占位
常见异常汇总
所有异常的超类:BaseException
Exception:所有异常的基类,因为所有python异常类都是基类Exception的其中一员,异常都是从基类Exception继承的,并且都在exceptions python 模块中定义。
- AssertionError assert(断言)语句失败
- AttributeError 试图访问一个对象没有的属性,比如foo.x ,但是foo没有x这个属性。
- ImportError 无法引入模块或者包,基本上是路径问题
- IndentationError 语法错误,代码没有正确对齐
- IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
- KeyError 试图访问字典里不存在的键
- NameError 使用一个还未被赋值予对象的变量
- SyntaxError Python代码非法,代码不能解释
- TypeError 传入对象类型与要求的不符
- UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另一个同名的全局变量,导致你以为正在访问它
- ValueError 传入一个调用者不期望的值,即使值的类型是正确的
- IOError 输入/输出异常,基本上是无法打开文件。
小结
本期是茶话会第三期,主要介绍了python的异常,介绍了什么是异常,如何正确处理异常以及常见的异常。异常很容易发生,如果因为异常导致程序崩溃是很不好的,虽然我们自己平时写一些小段的代码时不会觉得有多重要,但是如同上面那个需要用户输入数据的程序,如果用户不懂异常,看到一串trace很容易被迷惑,不知道问题出在哪儿,如果用户想要不怀好意,甚至可以通过trace获取我们不希望用户知道的信息,这是很危险的,很多训练有素的攻击者会根据这些信息判断出怎样对我们的代码发起攻击,这都是后面当我们参与到一些大型项目时需要注意的东西,虽然我们现在还处于新手阶段,但是需要养成良好的习惯,就像最初敲代码时需要遵从规范一样。今天的分享到此就全部结束啦,感谢大家!
PS
这是小苏第二次与大家见面了,上周因为自己有其它事情导致一直没有时间更新,所以整整延迟了一周,还是自己没有分配好时间,后面小苏会尽量调整好时间,准时与大家见面昂qwq!