Python之测试

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 模块中定义。

  1. AssertionError assert(断言)语句失败
  2. AttributeError 试图访问一个对象没有的属性,比如foo.x ,但是foo没有x这个属性。
  3. ImportError 无法引入模块或者包,基本上是路径问题
  4. IndentationError 语法错误,代码没有正确对齐
  5. IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
  6. KeyError 试图访问字典里不存在的键
  7. NameError 使用一个还未被赋值予对象的变量
  8. SyntaxError Python代码非法,代码不能解释
  9. TypeError 传入对象类型与要求的不符
  10. UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另一个同名的全局变量,导致你以为正在访问它
  11. ValueError 传入一个调用者不期望的值,即使值的类型是正确的
  12. IOError 输入/输出异常,基本上是无法打开文件。

小结

本期是茶话会第三期,主要介绍了python的异常,介绍了什么是异常,如何正确处理异常以及常见的异常。异常很容易发生,如果因为异常导致程序崩溃是很不好的,虽然我们自己平时写一些小段的代码时不会觉得有多重要,但是如同上面那个需要用户输入数据的程序,如果用户不懂异常,看到一串trace很容易被迷惑,不知道问题出在哪儿,如果用户想要不怀好意,甚至可以通过trace获取我们不希望用户知道的信息,这是很危险的,很多训练有素的攻击者会根据这些信息判断出怎样对我们的代码发起攻击,这都是后面当我们参与到一些大型项目时需要注意的东西,虽然我们现在还处于新手阶段,但是需要养成良好的习惯,就像最初敲代码时需要遵从规范一样。今天的分享到此就全部结束啦,感谢大家!

PS
这是小苏第二次与大家见面了,上周因为自己有其它事情导致一直没有时间更新,所以整整延迟了一周,还是自己没有分配好时间,后面小苏会尽量调整好时间,准时与大家见面昂qwq!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352

推荐阅读更多精彩内容