Python文件和异常之异常

异常

Python使用称之为异常的特殊对象来管理程序执行期间发生的错误。每当发生让Python不知所措的错误时,都会创建一个异常对象如果在代码中编写了处理这些异常的代码,程序将继续运行;如果未对异常进行处理,程序将停止,并显示一个traceback,其中包含有关异常的报告
异常是使用try-except代码块处理的。try-except代码块让Python执行指定的操作,同时告诉Python发生异常时怎么办,使用了try-except代码块让python执行指定的操作,同时告诉python发生异常时怎么办。使用try-except代码块时,即便出现异常,程序也将继续运行。显示你编写的友好的错误消息,而不是令用户迷惑的traceback反馈。

1.处理ZeroDivisionError异常

接下来就看一组导致Python引发异常的简单错误。我们都知道在数学中数字0不能做分母,然后呢,我们编写一段代码,看看python遇到分母为0的情况怎么处理:
division.py

print(5/0)

结果出错了:

Exception has occurred: ZeroDivisionError
division by zero
  File "C:\Users\Administrator\Desktop\python\0503\division.py", line 1, in <module>
    print(5/0)

在上面这种情况下,python将停止运行程序,并指出引发了那种异常,而我们可以根据这些信息对程序进行修改。

2.使用try-except代码块

当我们认为可能发生了错误时,可编写一个try-except代码块来处理可能引发的异常,让python尝试运行一些代码,并告诉它如果这些代码引发了指定的异常,该怎么处理。
处理ZeroDivisionError异常的try-except代码块类似于下面这样:

try:
	print(5/0)
except ZeroDivisionError:
	print("You can't divide by zero!")
You can't divide by zero!

如果try代码块中的代码运行起来没有问题,Python将跳过except代码块;如果try代码块中的代码导致了错误,Python将查找这样的except代码块,并运行其中的代码,即其中指定的错误与引发的错误相同。这样,用户看到的是一条友好的错误消息,而不是traceback。

3.使用异常避免崩溃

发生错误时,如果程序还有工作没有完成,妥善地处理错误就尤其重要。这种情况经常会出现在要求用户提供输入的程序中;如果程序能够妥善地处理无效输入,就能在提示用户提供有效输入,而不至于崩溃。
下面来创建一个只执行除法运算的简单计算器:
division.py

print("Give me two numbers, and I'll 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)

结果在输入分母时,出现了错误:
在这里插入图片描述
我们可以想想,在我们使用智能设备上面的计算器app时,不小心把0作为了除数,然后计算器app卡死了或者把智能设备给搞崩溃了,给用户的体验效果多差劲,还不纷纷退货或者把客户反馈邮箱给塞爆啊,所以说程序崩溃很不好,并且那些懂点技术的用户,脑子里面有什么坏坏的小心思,通过traceback信息知道了程序文件的名称,并且还可以看到部分代码,那可就不好了。

4.else代码块

通过将可能引发错误的代码放在try-except代码块中,可提高这个程序抵御错误的能力。错误执行除法运算的代码行导致的,因此我们需要将它放到try-except代码块中。示例中还包含一个else代码块;依赖try代码块成功执行的代码都应放到else代码块中:

print("Give me two numbers, and I'll 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
    try:
        answer = int(first_number) / int(second_number)
    except ZeroDivisionError:
        print("You can't divide by zero!")
    else:
        print(answer)

Give me two numbers, and I'll divide them.
Enter 'q' to quit.

First number: 5
Second number: 0
You can't divide by zero!

First number: 5
Second number: 3
1.6666666666666667

First number: q

就像当我们在计算器中输入5/0时,计算器就会提示错误消息一样,我们在代码中也提示用户一条错误消息,然后再次让用户输入,用户不会看到app卡死的现象,提升了用户使用的友好性。
try-except-else代码块的工作原理大致如下:python尝试执行try代码块中的代码;只有可能引发异常的代码才需要放在try语句中。有时候,有一些仅在try代码块成功执行时才需要运行的代码;这些代码应该放在else代码块中。except代码块告诉python,如果它尝试运行try代码块中的代码时引发了指定的异常,该怎么办。

5.处理FileNotFoundError异常

使用文件时,一种常见的问题是找不到文件:要查找的文件可能在其他的地方、文件名可能不正确或者要查找的文件根本就不存在。对于所有这些情形,都可使用try-except代码块以直观的方式进行处理。
下面就看一个具体的例子,文件alice.txt是不存在的。
alice.py

filename = 'alice.txt'

with open(filename) as file_object:
    contents = file_object.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)
Sorry,the file alice.txt does not exist.

感觉这样的异常处理也没有什么意思是吧,不久是一个简短的提示吗?那我们下面就在举一个例子来看看。

6.分析文本

可以分析包含整本书的文本文件。下面来尝试提取陪伴我们很多人童年的童话(Alice in Wonderland)文本,并尝试计算它包含多少个单词,我们将使用方法split(),它根据一个字符串创建一个单词列表。我们暂时只对包含“Alice in Wonderland”的字符串调用方法split()的结果:

>>> title = "Alice in Wonderland"
>>> title.split()
['Alice', 'in', 'Wonderland']

方法split()以空格为分隔符将字符串分拆成多个部分,并将这些部分都存储到一个列表中。结果是一个包含字符串中所有单词的列表,虽然有些单词可能包含标点。为计算Alice in Wonderland包含多少个单词,我们将对整篇小说调用split(),再计算得到的列表包含多少个元素,从而确定整篇童话大致包含多少个单词:

filename = 'D:\python\《Python编程》源代码文件-更新\《Python编程》源代码文件\chapter_10\\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)
else:
    """计算文件大致包含多少个单词"""
    words = contents.split()
    num_words = len(words)
    print("The file " + filename + " has about " + str(num_words) + " words. ")

output:

The file D:\python\《Python编程》源代码文件-更新\《Python编程》源代码文件\chapter_10\alice.txt has about 29461 words.

在例子中我们使用了绝对路径,但是注意在路径的最后,文件名之前的反斜杠是两个。

7.使用多个文件

下面再多分析几本书。我们先将这个程序的大部分逻辑代码移到一个名为count_words()的函数中,这样呢,对多本书进行分析时将更容易:

def count_words(filename):
    """计算一个文件大致包含多少个单词"""
    try:
        with open(filename) as f_obj:
            contents = f_obj.read()
    except FileNotFoundError:
         msg = "Sorry,the file " + filename + " does not exist. "
         print(msg)
    else:
        """计算文件大致包含多少个单词"""
        words = contents.split()
        new_words = len(words)
        print("The file " + filename + "has about " + str(new_words) + " words. ")
    
filenames = [
                'D:\python\《Python编程》源代码文件-更新\《Python编程》源代码文件\chapter_10\\alice.txt',
                'siddhartha.txt','moby_dick.txt','D:\python\《Python编程》源代码文件-更新\《Python编程》源代码文件\chapter_10\little_women.txt'
            ]
for filename in filenames:
    count_words(filename)```
output:
```python
The file D:\python\《Python编程》源代码文件-更新\《Python编程》源代码文件\chapter_10\alice.txthas about 29461 words.
Sorry,the file siddhartha.txt does not exist.
Sorry,the file moby_dick.txt does not exist.
The file D:\python\《Python编程》源代码文件-更新\《Python编程》源代码文件\chapter_10\little_women.txthas about 189079 words.

代码中中间两个文件不存在,没有影响到后续代码的执行。
在代码中,使用try-except代码块提供了两个重要的优点:避免让用户看到traceback;让程序能够继续分析能够找到的其他文件。

8.失败时一声不吭

有的时候,并非每次发生异常的时候,都需要提示用户出现异常了,有可能就什么提示也没有(不说话,只是看看),在except代码块中就什么也不做,python有一个pass语句,可在代码块中使用它来让python什么都不做:

def count_words(filename):
    """计算一个文件大致包含多少个单词"""
    try:
        with open(filename) as f_obj:
            contents = f_obj.read()
    except FileNotFoundError:
         pass
    else:
        """计算文件大致包含多少个单词"""
        words = contents.split()
        new_words = len(words)
        print("The file " + filename + "has about " + str(new_words) + " words. ")
    
filenames = [
                'D:\python\《Python编程》源代码文件-更新\《Python编程》源代码文件\chapter_10\\alice.txt',
                'siddhartha.txt','moby_dick.txt','D:\python\《Python编程》源代码文件-更新\《Python编程》源代码文件\chapter_10\little_women.txt'
            ]
for filename in filenames:
    count_words(filename)

output:

The file D:\python\《Python编程》源代码文件-更新\《Python编程》源代码文件\chapter_10\alice.txthas about 29461 words.
The file D:\python\《Python编程》源代码文件-更新\《Python编程》源代码文件\chapter_10\little_women.txthas about 189079 words.

pass语句还充当了占位符,它提醒在程序中的某个地方射门都没有做,就像在C语言中,什么也不做时就摆放一对括号,必须要有括号,当然在C语言中一般时不建议使用这样什么也不做的空语句,除非有特殊的应用需求。

练习:

print("Wellcome use calculate!")

while True:
    value = input("please enter value: ")
    if value == 'q':
        break
    value = int(value)
    print(value)

output:发生了如下的错误:
在这里插入图片描述
怎么处理呢?属于ValueError.

print("Wellcome use calculate!")

while True:
    value = input("please enter value: ")
    if value == 'q':
        break
    try:
        value = int(value)
    except ValueError:
        pass
    else:
        print(value)

output:这次可以了

Wellcome use calculate!
please enter value: 1
1
please enter value: 2
2
please enter value: 3
3
please enter value: 4
4
please enter value: w
please enter value: e
please enter value: r
please enter value: t
please enter value: q

练习:

filename = 'D:\python\《Python编程》源代码文件-更新\《Python编程》源代码文件\chapter_10\\alice.txt'
value = 0
try:
    with open(filename) as f:
        contents = f.read()
        words = contents.split()
        count  = len(words)
        print(count)
        print(contents.lower().count('the'))
        print(contents.rstrip())
except FileNotFoundError:
     pass
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值