10.3异常
1.处理ZeroDivisionError异常
我们知道0不能作除数
在上述traceback中,上面指出的错误ZeroDivisionError 是一个异常对象。
Python无法按你的要求做时,就会创建这种对象。在这种情况下,Python将停止运行程序,并指出 引发了哪种异常,而我们可根据这些信息对程序进行修改。
下面我们将告诉Python,发生这种错误时怎么办。
2.使用try–except代码块
try:
print(5/0)
except ZeroDivisionError:
print("you cant divide by zero")
我们将导致错误的代码行print(5/0) 放在了一个try 代码块中。
如果try 代码块中的代码运行起来没有问题,Python将跳过except 代码块;
如果try 代码块中的代码导致了 错误,Python将查找这样的except 代码块,并运行其中的代码,即其中指定的错误与引发的错误相同。
这样,用户看到的是一条友 好的错误消息,而不是traceback:
3.使用异常避免崩溃
简单计算器:
print("Give me two numbers,and i will divide them")
print("Enter q to quit")
while True:
first_number=input('\nFirst number:')
if first_number=='q':
break
second_number=input('\nSecond number:')
if second_number=='q':
break
answer=int(first_number)/int(second_number)
print(answer)
通过将可能引发错误的代码放在try-except 代码块中,可提高这个程序抵御错误的能力。错误是执行除法运算的代码行导致的,因此我们需要将它放到try-except 代码块 中。
4.else代码块
print("Give me two numbers,and i will divide them")
print("Enter q to quit")
while True:
first_number=input('\nFirst number:')
if first_number=='q':
break
second_number=input('\nSecond number:')
try:
answer=int(first_number)/int(second_number)
except ZeroDivisionError:
print("you cant divide by 0!")
else:
print(answer)
运行结果:
try-except-else 代码块的工作原理大致如下:
Python尝试执行try 代码块中的代码;只有可能引发异常的代码才需要放在try 语句中。
有时候,有一些仅在try 代码块成功 执行时才需要运行的代码;这些代码应放在else 代码块中。
except 代码块告诉Python,如果它尝试运行try 代码块中的代码时引发了指定的异常,该怎么办。
5.处理FileNotFoundError
当我们创建了alice.txt文件但是没有放在该文件目录下的时候。
运行代码块:
filename='alice.txt'
with open(filename) as f_obj:
contents=f_obj.read()
会发生FileNotFoundError异常:这是Python找不到要打开的文件时创建的异常。
在这个示例中,这个错误是函数open() 导致的,因此要处理 这个错误,必须将try 语句放在包含open() 的代码行之前:
filename='alice.txt'
try:
with open(filename) as f_obj:
contents=f_obj.read()
except FileNotFoundError:
msg="Sorry,the file "+filename+' does not exist.'
print(msg)
运行结果:
6.分析文本
方法split() 以空格为分隔符将字符串分拆成多个部分,并将这些部分都存储到一个列表中。结果是一个包含字符串中所有单词的列表,虽然有些单词可能包含标点。
为计算 Alice in Wonderland 包含多少个单词,我们将对整篇小说调用split() ,再计算得到的列表包含多少个元素,从而确定整篇童话大致包含多少个单词:
def count_words(filename):
"""计算一个文件中大致包含多少个单词"""
try:
with open(filename) as f_obj:
contents=f_obj.read()
except FileNotFoundError:
msg="Sorry,the file"+filename+"does not found"
print(msg)
else:
#计算文件中大致包含多少个单词
words=contents.split()
num_words=len(words)
print("The file "+filename+' has about '+str(num_words)+" words")
filename='alice.txt'
count_words(filename)
可以建立filenames列表,即使这些文件不存在也不影响程序执行。
def count_words(filename):
"""计算一个文件中大致包含多少个单词"""
try:
with open(filename) as f_obj:
contents=f_obj.read()
except FileNotFoundError:
msg="Sorry,the file"+filename+"does not found"
print(msg)
else:
#计算文件中大致包含多少个单词
words=contents.split()
num_words=len(words)
print("The file "+filename+' has about '+str(num_words)+" words")
filenames = ['alice.txt', 'siddhartha.txt', 'moby_dick.txt', 'little_women.txt']
for filename in filenames:
count_words(filename)
8.失败时一声不吭
有时候你希望程序在发生异常时一声不吭,就像什么都没有发生一样继续运行。
Python有一个pass 语句,可在代码块中使用它来让Python 什么都不要做:
def count_words(filename):
"""计算一个文件中大致包含多少个单词"""
try:
--snip--
except FileNotFoundError:
pass
else:
#计算文件中大致包含多少个单词
--snip--
filenames = ['alice.txt', 'siddhartha.txt', 'moby_dick.txt', 'little_women.txt']
for filename in filenames:
count_words(filename)
9.决定报告那些错误
编写得很好且经过详尽测试的代码不容易出现内部错误,如语法或逻辑错误,但只要程序依赖于外部因素,如用户输入、存在指定的文件、有网络链接,就有可能出现异常。
凭借经验可判断该在程序的什么地方包含异常处理块,以及出现错误时该向用户提供多少相关的信息。
练习
1 . 加法运算 :提示用户提供数值输入时,常出现的一个问题是,用户提供的是文本而不是数字。在这种情况下,当你尝试将输入转换为整数时,将引 发TypeError 异常。
编写一个程序,提示用户输入两个数字,再将它们相加并打印结果。在用户输入的任何一个值不是数字时都捕获TypeError 异常,并打印一条友好的错误消息。对你编写的程序进行测试:先输入两个数字,再输入一些文本而不是数字。
print('Enter two numbers and i will add them')
while True:
try:
first_num=input("first number:")
second_num=input("second number:")
answer=int(first_num)+int(second_num)
except ValueError:
print("please enter numbers instead of texts.")
else:
print(answer)
运行结果:
2.猫和狗 :创建两个文件cats.txt和dogs.txt,在第一个文件中至少存储三只猫的名字,在第二个文件中至少存储三条狗的名字。
编写一个程序,尝试读取这些文件, 并将其内容打印到屏幕上。将这些代码放在一个try-except 代码块中,以便在文件不存在时捕获FileNotFound 错误,并打印一条友好的消息。将其中一个文件 移到另一个地方,并确认except 代码块中的代码将正确地执行。
def read_file(filename):
try:
with open(filename)as f_obj:
contents=f_obj.read()
print(contents)
except FileNotFoundError:
msg='Sorry,the file:'+filename+' does not exist.'
print(msg)
filenames=['cats.txt','dogs.txt','birds.txt']
for filename in filenames:
read_file(filename)
运行结果:
3 . 沉默的猫和狗 :修改你在练习2中编写的except 代码块,让程序在文件不存在时一言不发。
def read_file(filename):
try:
with open(filename)as f_obj:
contents=f_obj.read()
print(contents)
except FileNotFoundError:
pass
filenames=['cats.txt','dogs.txt','birds.txt']
for filename in filenames:
read_file(filename)
运行结果:
4.常见单词 :访问项目Gutenberg(http://gutenberg.org/ ),并找一些你想分析的图书。下载这些作品的文本文件或将浏览器中的原始文本复制到文本文件中。
你可以使用方法count() 来确定特定的单词或短语在字符串中出现了多少次。例如,下面的代码计算’row’ 在一个字符串中出现了多少次:
请注意,通过使用lower() 将字符串转换为小写,可捕捉要查找的单词出现的所有次数,而不管其大小写格式如何。
编写一个程序,它读取你在项目Gutenberg中获取的文件,并计算单词’the’ 在每个文件中分别出现了多少次。
filename='alice.txt'
with open(filename) as file_object:
lines=file_object.read()
times=lines.lower().count('the')
print(times)