上次作业参考答案:
本次测试:
Question9
Level2
Question
Write a program that accepts sequence of linesasinputandprints the lines after makingallcharactersinthe sentence capitalized.
Supposethe followinginputissupplied to the program:
Hello world
Practice makes perfect
Then,the output should be:
HELLO WORLD
PRACTICE MAKES PERFECT
写一程序,接收来自键盘的输入,输入一行,然后另一行,如果不输入,敲击enter键后打印出大写状态,比如:输入,
Hello world
Procatice makes perfect
enter键后
打印出大写的两行。
今天,学习MIT编程导论第七章,异常与断言
我们先按照书的顺序,将教授哲学式的论述,注重方法论的观点罗列一下,然后,附上一篇我翻译的关于(错误与异常)的文章,其来自英文的Python入门材料。说是入门,但语法很系统也很全面,几乎对任何学习Python的人都有用。我已经将这个英文材料发送到我的QQ群,群号为:939945579,群名为(Mark学编程),请感兴趣的直接入群下载即可,中文翻译正在加紧。有需要部分中文翻译的可以联系我,直接赠送已经翻译的部分。
书中教授说道:“异常”通常被定义为“不合理的事情”,因此不太常见。但是在Python中,没有比异常更常见的了。如果,你不是纸上谈兵,应该已经敲了不少代码,也就已经遇到了很多异常或者错误,如图我故意做了好多错误异常,供参考:
我仅仅标出了上面三个,下面还有大量的。看这个英文的秘诀,就是只看最下面一行的解释就行,其实最常见的就是SyntaxError, NameErro, TyepError等。
处理异常
发生异常时,程序会终止,然后我们会查看代码,试着找出错误的地方,这才是真正程序员伤心的地方,有的时候可能就是一个括号漏到了,就可能让你几十个小时消耗了。当然,初学者这几行代码,虽然对初学者的你是个挑战,但大不了先暂时不管它。然而,学习处理异常,是我们必须要掌握的内容。
比如下面的代码:
succFailRatio = numSucc / float(numFail) # 成功失败比例=成功数量/失败数量,float 将numFail转化成浮点类型,使得除法可以小数化。
这个时候要考虑到numFail如果取值0怎么办,这就是事先处理可能的异常。而try..except语句提供了一个很好的处理异常的方法。参见下列代码
try:
succFailRatio = numSucc / float(numFail)
print ("The success / failure ratio is ', succFailRatio)
except ZeroDivisionError:
print ("No failures so ratio is undefined")
限于篇幅,不再解释和运行,请自行测试。
另一个例子:
val = int(input("Enter an integer: ")
print ('The square of the number you entered is ', val**2)
以上代码,如果输入的是整数,OK, 没有问题,但如果你不小心输入了 abc 就会导致程序报错,你可以试试看。如果出错,后面的print就不会运行了。这段代码换成 try..except就是这样的:
while True:
val = input('Enter an integer: ')
try:
val = int(val)
print ('The square of the number you entered is ', val**2)
break
except ValueError:
print (val, ' is not an integer')
还是自行测试,不再解释,因为后面所附的材料会帮助你理解。
2 行的代码变成了8行,如果很多地方需要这个代码,那就将它编程函数,好像很简单,是不是?就在上面放上一个 def readInt( ): 然后,将try里面的 print 变成return val,如何?如果你没有成功转换成函数,请你一定翻开前面的内容补课。 运行一下试试看,行不行。
下面是作者将这个代码扩展到接受任意类型的输入并检测输入是否属于某种类型,其实这也是解决问题的一种方法,先窄后宽,先具体后抽象。如图:
上面的代码运行时,还有很大的挑战,多做几次试验吧。
本书中还有两个内容,把异常当作控制流来使用,以及断言,考虑到有些难度,况且加上下面的附上的材料,已经超负荷了。就此打住吧。以后还有机会论述这些东西。
以下是所附材料,更系统的讲解了异常与错误的问题。
异常
当程序中出现意外情形时,异常就出现了。比如,你准备读取文件,而文件不在会怎样?或者当你在运行程序时,你意外的删除了程序或程序的一部分?此类情形会被程序的异常机制所处理。
类似的,如果你的代码有些错误的语句?这时候Python会举手示意,告诉你有个错误。
错误
考虑一下简单的print函数调用,如果我们误拼写成Print(第一个字母大写了),在这种情况下,Python抛出语法错误警示。
>>> Print("HelloWorld")
Traceback (mostrecent call last):
File "", line 1, in
NameError:name'Print'is not defined
>>> print("HelloWorld")
HelloWorld
第一行代码,Python抛出错误警示,是个NameError。警示里面还包括出错的地方,(请注意,出错的地方仅仅是参考,目前Python还没有聪明到很准备的指出错误所在,所以需要活人找出错误)。
意外
我们将要尝试从用户那里读取输入,当你电脑出现输入提示符时,按理应该输入第一行并且点击enter键,但你误击Ctrl-z键组合(假如你的电脑是win系统)。看看发生了什么?
>>> s = input('Entersomething --> ')
Enter something --> Traceback (mostrecentcall last):
File "", line 1, in
EOFError
Python抛出的错误叫做 EOFError, 这应该意味着,Python发现了 “文件结束”符号,当然,这是你误操作引起的。
处理异常
我们使用 try...except语句来处理意外,基本的做法就是将 正常代码语句放入到 try-block 之中。然后将错误处理代码放到except-block。
举例:
try:
text = input('Entersomething --> ')
except EOFError:
print('Why did you doanEOF onme?')
except KeyboardInterrupt:
print('You cancelled the operation.')
else:
print('You entered {}'.format(text))
光看不练假把式,你需要在电脑上练习至少一遍。我的电脑ctr-c貌似失效。所以,练习很重要。结果我用ctr + F2解决
代码运行原理
我们将所有可能引起的异常/错误放在了try语句块,将恰当的错误/异常处理语句放到了except 语句中。except语句可以处理单个特定的错误或异常,可以处理括号内一系列错误或异常。如果没有异常/错误名称出现,语句将处理所有的错误和异常。(补充:读者没有必要辨别错误与异常的区别)
请注意,只是有一个except语句与try语句关联,否则,为什么要使用try语句呢?
如果有异常和错误,但没有被明文处理,则进入default Python handler,它会停止运行代码并打印错误信息。
你可以用else语句与try..except关联。如果没有异常出现,则执行这个else语句。
在下面的例子里,我们将看到如何获取异常对象,从而使我们得到一些额外信息。
抛出异常
你可以用raise语句抛出异常,通过提供错误/异常名称以及需要抛出的异常对象。
你可以抛出的错误或异常应该是个类,它直接或间接从Python的 Exception 类中延伸(继承)而来。
举例:
榜样的力量是无穷的,请跟随练习
代码工作机制
我们在这里创建了自己的类。叫做ShortInputException类。它有两个字段,length是输入长度,atleast 是程序期望的最低输入长度。
在except 语句中,我们使用了as 引入一个变量名来绑定对应的错误/异常对象(不用诧异,一切皆对象),并且我们使用这个变量名来表示,用点来引用对象中的两个属性(字段)length, atleast。
Try .. Finally语句
假设你的程序正在读取文件,你怎样才能确保文件对象被正确关闭,不管是否有异常发生?这可以用finally语句在做。
举例:
请注意,你先用Control+ c键,如果不行,试试F2,再不行,就跳过。编程有时就是这样,不知道哪儿出错了,可以跳过。等有机会再修复。
我们正常文件读取,但我们放入了一个2秒的睡眠时间。这样程序运行就有间隔了。当程序仍然运行时,按下Ctrl+c键,有的电脑可能不行,可以使用其他键。中断/撤销程序。
注意,这时候KeyboardInterrupt异常抛出,程序退出。但是,我们的finally语句在程序退出前执行了。文件对象被关闭。
with语句
在try语句块获取资源,随后在finally语句块释放资源是个好的模式。With语句使得这一做法以更清洁的方式达到。
with open("poem.txt") asf:
for line in f:
print(line,end='')
代码运行原理
输出结果和上一个应该一样。区别在于使用了with语句,我们将关闭文件的事给了with open自动处理。
在幕后真正发生的是,with语句里面有个协议,open语句返回了一个对象,我们称之为文件对象,在此案例中我们命名为“thefile”,有个这样的方法thefile.__enter__总是在open下面的代码执行前调用,并且在代码后调用thefile.__exit__. 所以我们再finally中执行的代码在这个__exit__就执行了。这就使我们不用精心的重复使用 try..finally语句了。
领取专属 10元无门槛券
私享最新 技术干货