第033讲:异常处理:你不可能总是对的2

目录

0. 请写下这一节课你学习到的内容:格式不限,回忆并复述是加强记忆的好方式!

测试题

0. 我们使用什么方法来处理程序中出现的异常?

1. 一个 try 语句可以和多个 except 语句搭配吗?为什么?g

2. 你知道如何统一处理多类异常吗?

3. except 后边如果不带任何异常类,Python 会捕获所有(try 语句块内)的异常并统一处理,但小甲鱼却不建议这么做,你知道为什么吗?

4. 如果异常发生在成功打开文件后,Python 跳到 except 语句执行,并没有执行关闭文件的命令(用户写入文件的数据就可能没有保存起来),因此我们需要确保无论如何(就算出了异常退出)文件也要被关闭,我们应该怎么做呢?}

5. 请恢复以下代码中马赛克挡住的内容,使得程序执行后可以按要求输出。

动动手

0. 还记得我们第一个小游戏吗?只要用户输入非整型数据,程序立刻就会蹦出不和谐的异常信息然后崩溃。请使用刚学的异常处理方法修改以下程序,提高用户体验。.

1. input() 函数有可能产生两类异常:EOFError(文件末尾endoffile,当用户按下组合键 Ctrl+d 产生)和 KeyboardInterrupt(取消输入,当用户按下组合键 Ctrl+c 产生),再次修改上边代码,捕获处理 input() 的两类异常,提高用户体验。

2. 尝试一个新的函数 int_input(),当用户输入整数的时候正常返回,否则提示出错并要求重新输入。%

3. 把文件关闭放在 finally 语句块中执行还是会出现问题,像下边这个代码,当前文件夹中并不存在"My_File.txt"这个文件,那么程序执行起来会发生什么事情呢?你有办法解决这个问题吗?


0. 请写下这一节课你学习到的内容:格式不限,回忆并复述是加强记忆的好方式!

上节课我们已经掌握了能够碰到的异常类型,name这一节我们就来学习如何检测这些异常并处理它们。异常检测我们可以使用 try 语句来实现,任何出现在 try 语句范围内的异常都会被检测到,我们这节课要介绍两个模式的 try 语句,

一种是 try—except 语句:

语法:try :

                       检测范围

           except  Exception  [ as  reason ]:

                      出现异常(Exception)后的处理代码

try:
        f = open('我是一个不存在的文件.txt')
        print(f.read())
        f.close
except OSError:
        print('文件出错啦')

============ RESTART: C:/Users/XiangyangDai/Desktop/上课代码/33-1.py ============
文件出错啦

这样处理对于用户来说很好,但是对于程序员来说,我们还想要知道报错的具体错误类型,这时,我们就使用可选参数 as reason(其中 reason 是一个变量,得到错误具体,需要 str(reason) 才能打印)

try:
        f = open('我是一个不存在的文件.txt')
        print(f.read())
        f.close
except OSError as reason:
        print('文件出错啦!\n错误的原因是:' + str(reason))

============ RESTART: C:/Users/XiangyangDai/Desktop/上课代码/33-1.py ============
文件出错啦!
错误的原因是:[Errno 2] No such file or directory: '我是一个不存在的文件.txt'

另外,一个 try 可以与多个 except 搭配,以监测多种类型的错误。但是在这种情况下,程序会在第一个出错的位置检查有没有对应的 except,如果有,就仅打印第一次出错的出错信息,如果没有第一个出错对应的except,则还是红色原始报错。

try:
        sum = 1 + '1'
        f = open('我是一个不存在的文件.txt')
        print(f.read())
        f.close
except OSError as reason:
        print('文件出错啦!\n错误的原因是:' + str(reason))
except TypeError as reason:
         print('类型出错啦!\n错误的原因是:' + str(reason))
============ RESTART: C:/Users/XiangyangDai/Desktop/上课代码/33-1.py ============
类型出错啦!
错误的原因是:unsupported operand type(s) for +: 'int' and 'str'

try:
        int('abc')    #ValueError
        sum = 1 + '1'    #类型错误 TypeError
        f = open('我是一个不存在的文件.txt')  #OSError
        print(f.read())
        f.close
except OSError as reason:
        print('文件出错啦!\n错误的原因是:' + str(reason))
except TypeError as reason:
         print('类型出错啦!\n错误的原因是:' + str(reason))
============ RESTART: C:/Users/XiangyangDai/Desktop/上课代码/33-1.py ============
Traceback (most recent call last):
  File "C:/Users/XiangyangDai/Desktop/上课代码/33-1.py", line 2, in <module>
    int('abc')    #ValueError
ValueError: invalid literal for int() with base 10: 'abc'

如果你想检测任何类型的错误,只要程序出错,就提示出错信息,不管是什么类型的错误:

try:
        int('abc')    #ValueError
        sum = 1 + '1'    #类型错误 TypeError
        f = open('我是一个不存在的文件.txt')  #OSError
        print(f.read())
        f.close
except :
        print('出错啦!')

============ RESTART: C:/Users/XiangyangDai/Desktop/上课代码/33-1.py ============
出错啦!

但是这种做法是不推荐的,因为这会隐藏程序员未想到的所有未准备好处理的异常和错误。例如当按住 ctrl + C 想停止程序时,也会检测为KeyboardError,而弹出提示信息。

要注意的是,try 语句的检测范围内一旦出现异常,剩下的语句将不会被执行。

第二种是 try — finally 语句:

语法:try:

                    检测范围

          except Exception [as reason]:

                   出现异常(Exception)后的处理代码

          finally:

                  无论如何都会被执行的代码

在上面的例子中,如果异常出现在打开文件之后,然后文件没有被关闭,这是非常不妥的。可以使用try — finally 语句改进。

try:
        f = open('C:\\Users\\XiangyangDai\\Desktop\\一个文件.txt', 'w')
        print(f.write('我存在了!'))    #这里会写入‘我存在了!’打印的是写入的字符数
        sum = 1 + '1'
except (OSError, TypeError):
        print('出错啦!')
finally:
        f.close()
============ RESTART: C:/Users/XiangyangDai/Desktop/上课代码/33-2.py ============
5
出错啦!

总结一下:如果 try 语句块里面没有任何运行的错误的时候,就会跳过 exception语句块,然后执行 finally 语句块里的内容,如果出现了异常,会根据异常的内容去找到对应的异常执行代码,然后还会执行 finally。也就是说,无论如何,finally语句块里的内容都是确保将被执行的内容。即使出现的异常在 exception 中没有定义对应的处理代码,finally 也会被执行。

最后说一下 raise 语句:

可以使用 raise 语句引发一个异常

>>> raise
Traceback (most recent call last):
  File "<pyshell#0>", line 1, in <module>
    raise
RuntimeError: No active exception to reraise
>>> raise ZeroDivisionError('除数为零的异常')
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    raise ZeroDivisionError('除数为零的异常')
ZeroDivisionError: 除数为零的异常

测试题

0. 我们使用什么方法来处理程序中出现的异常?

答:使用 try……except 搭配来捕获处理程序中出现的异常。"Xj=$)R
try:版权属于:bbs.fishc.com
        检测范围来自:bbs.fishc.com
except Exception[as reason]:r&Fijw]E
        出现异常(Exception)后的处理代码
Y%

1. 一个 try 语句可以和多个 except 语句搭配吗?为什么?g

答:可以。因为 try 语句块中可能出现多类异常,利用多个 except 语句可以分别捕获并处理我们感兴趣的异常。

try:
    sum = 1 + '1'
    f = open('我是一个不存在的文档.txt')
    print(f.read())
    f.close()
except OSError as reason:
    print('文件出错啦T_T\n错误原因是:' + str(reason))
except TypeError as reason:
    print('类型出错啦T_T\n错误原因是:' + str(reason))

2. 你知道如何统一处理多类异常吗?

答:在 except 后边使用小括号“()”把多个需要统一处理的异常括起来:

try:
    int('abc')
    sum = 1 + '1'
    f = open('我是一个不存在的文档.txt')
    print(f.read())
    f.close()
except (OSError, TypeError):
    print('出错啦T_T\n错误原因是:' + str(reason))

3. except 后边如果不带任何异常类,Python 会捕获所有(try 语句块内)的异常并统一处理,但小甲鱼却不建议这么做,你知道为什么吗?

答:因为它会隐藏所有程序员未想到并且未做好准备处理的错误,例如用户输入ctrl+c试图终止程序会被解释为KeyboardInterrupt异常。

4. 如果异常发生在成功打开文件后,Python 跳到 except 语句执行,并没有执行关闭文件的命令(用户写入文件的数据就可能没有保存起来),因此我们需要确保无论如何(就算出了异常退出)文件也要被关闭,我们应该怎么做呢?}

答:我们可以使用 finally 语句来实现,如果 try 语句块中没有出现任何运行时错误,会跳过 except 语句块执行 finally 语句块的内容。

如果出现异常,则会先执行 except 语句块的内容再接着执行 finally 语句块的内容。总之,finally 语句块里的内容就是确保无论如何都将被执行的内容!

5. 请恢复以下代码中马赛克挡住的内容,使得程序执行后可以按要求输出。

代码:Powered by bbs.fishc.com

输出:版权属于:bbs.fishc.com

 答:这道题比较考脑瓜,你想到了吗?

try:
    for i in range(3):
        for j in range(3):
            if i == 2:
                raise KeyboardInterrupt
            print(i, j)
except KeyboardInterrupt:
    print('退出啦!')

动动手

0. 还记得我们第一个小游戏吗?只要用户输入非整型数据,程序立刻就会蹦出不和谐的异常信息然后崩溃。请使用刚学的异常处理方法修改以下程序,提高用户体验。.

猜数字小游戏:

import random

secret = random.randint(1,10)
print('------------------我爱鱼C工作室------------------')
temp = input("不妨猜一下小甲鱼现在心里想的是哪个数字:")
guess = int(temp)
while guess != secret:
    temp = input("哎呀,猜错了,请重新输入吧:")
    guess = int(temp)
    if guess == secret:
        print("我草,你是小甲鱼心里的蛔虫吗?!")
        print("哼,猜中了也没有奖励!")
    else:
        if guess > secret:
            print("哥,大了大了~~~")
        else:
            print("嘿,小了,小了~~~")
print("游戏结束,不玩啦^_^")

答:这里对可能导致异常的 guess = int(temp) 进行监测F&2()k"]
0PR3=c8!2xXw*Zl[Ir|sW<7"Bg@
代码清单:

import random

secret = random.randint(1,10)
print('------------------我爱鱼C工作室------------------')
temp = input("不妨猜一下小甲鱼现在心里想的是哪个数字:")
try:    
    guess = int(temp)
except ValueError:
    print('输入错误!')
    guess = secret
while guess != secret:
    temp = input("哎呀,猜错了,请重新输入吧:")
    guess = int(temp)
    if guess == secret:
        print("我草,你是小甲鱼心里的蛔虫吗?!")
        print("哼,猜中了也没有奖励!")
    else:
        if guess > secret:
            print("哥,大了大了~~~")
        else:
            print("嘿,小了,小了~~~")
print("游戏结束,不玩啦^_^")

1. input() 函数有可能产生两类异常:EOFError(文件末尾endoffile,当用户按下组合键 Ctrl+d 产生)和 KeyboardInterrupt(取消输入,当用户按下组合键 Ctrl+c 产生),再次修改上边代码,捕获处理 input() 的两类异常,提高用户体验。

答:

import random

secret = random.randint(1,10)
print('------------------我爱鱼C工作室------------------')
try:
    temp = input("不妨猜一下小甲鱼现在心里想的是哪个数字:")    
    guess = int(temp)
except (ValueError, EOFError, KeyboardInterrupt):
    print('输入错误!')
    guess = secret
while guess != secret:
    temp = input("哎呀,猜错了,请重新输入吧:")
    guess = int(temp)
    if guess == secret:
        print("我草,你是小甲鱼心里的蛔虫吗?!")
        print("哼,猜中了也没有奖励!")
    else:
        if guess > secret:
            print("哥,大了大了~~~")
        else:
            print("嘿,小了,小了~~~")
print("游戏结束,不玩啦^_^")

2. 尝试一个新的函数 int_input(),当用户输入整数的时候正常返回,否则提示出错并要求重新输入。%

程序实现如图:版权属于:bbs.fishc.com

 答:

def int_input(prompt=''):
    while True:
        try:
            int(input(prompt))
            break
        except ValueError:
            print('出错,您输入的不是整数!')

int_input('请输入一个整数:')

3. 把文件关闭放在 finally 语句块中执行还是会出现问题,像下边这个代码,当前文件夹中并不存在"My_File.txt"这个文件,那么程序执行起来会发生什么事情呢?你有办法解决这个问题吗?

try:
    f = open('My_File.txt') # 当前文件夹中并不存在"My_File.txt"这个文件T_T
    print(f.read())
except OSError as reason:
    print('出错啦:' + str(reason))
finally:
f.close()

答:由于finally语句块里试图去关闭一个并没有成功打开的文件,因此会弹出错误内容如下:

>>> 出错啦:[Errno 2] No such file or directory: 'My_File.txt'
Traceback (most recent call last):
  File "C:\Users\FishC000\Desktop\test.py", line 7, in <module>
    f.close()
NameError: name 'f' is not defined

我们这样修正:

try:
    f = open('My_File.txt') # 当前文件夹中并不存在"My_File.txt"这个文件T_T
    print(f.read())
except OSError as reason:
    print('出错啦:' + str(reason))
finally:
    if 'f' in locals(): # 如果文件对象变量存在当前局部变量符号表的话,说明打开成功
        f.close()

猜你喜欢

转载自blog.csdn.net/qq_41556318/article/details/84310407