python学习041-----python之异常处理(二):检测并处理异常

检测并处理异常
异常检测可以使用try语句,任何出现在try语句中的异常都会被检测到。这里我们主要介绍两种
形式的try语句:
-----------------------------------------------------------------------------------------------
1. try-except语句,格式如下:
try:
    检测范围
except Exception[ as reason ]:
    出现异常(Exception)后的处理代码

-----------------------------------------------------------------------------------------------
举例说明:
当我们打开一个不存在的文件的时候,系统会报错。我们把有可能出错的代码放到try-except语
句中,查找python异常总结(上一篇文章)知:操作系统出现异常时的错误为OSError,将其写在
except后,在代码出现OSError类型的错误时我们便能捕捉到它。

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

【输出】文件出错了!
如果我们想进一步知道是哪种类型的OSError,可以使用except的as reason参数来打印错误。值
得注意的是,reason是变量,名字是我们可以随意定义的

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

【输出】
文件出错了!
错误的原因是: [Errno 2] No such file or directory: '一个不存在的文件.txt'

另外: 一个try还可以和多个except进行搭配,以对我们感兴趣的错误进行捕获。举例:

try:
    int('abc')            #非数字字符串不能强制转换为整型,属于ValueError 
    sum = 1 + '1'    #整型和字符串类型不能相加,属于TypeError
    f = open('一个不存在的文件.txt')
    print(f.read())
    f.close()
except OSError as reason:
    print('文件出错了!\n错误的原因是:',reason)
except TypeError as reason:
    print('类型出错了!\n错误的原因是:',reason)
except ValueError as reason:
    print('参数出错了!\n错误的原因是:',reason)

【输出】
参数出错了!
错误的原因是: invalid literal for int() with base 10: 'abc'

值得注意的是:
程序会最先显示ValueError,当第44行的ValueError被改正后才会接着显示第45行的TypeError,
以此类推。另外,我们也可以将几种不同类型的错误写在同一个except里:

try:
    int('abc')
    sum = 1 + '1'
except (TypeError, ValueError):
    print('出错了!')

【输出】出错了!
-----------------------------------------------------------------------------------------------
2. try-finally语句,格式如下:
try:
    检测范围
except Exception [as reason]:
    出现异常(Exception)后的处理代码
finally:
    无论如何都执行的代码

-----------------------------------------------------------------------------------------------
这个语句可以弥补上一个语句的不足,比如上一个例子中,如果文件在打开后跳到了except语句
中,那么关闭文件语句就不会被执行了。也就是说文件内容并不会被写入,而是一直滞留在缓冲
区内。这样显然是不合理的。(PS:这个问题在python3中已经被纠正了,这里仅以python2举例来
说明问题。)如果这么写,上面的问题就不会再发生了:

try:
    f = open('我为什么是一个文件.txt','w')
    f.write('我存在了!')
    sum = 1+ '1'
except (OSError, TypeError):
    print('出错了!')
finally:
    f.close()

最后我们谈一下raise语句我们可以通过raise语句引发一个异常。也就是说我们可以用raise语
句自定义异常,这样我们就可以在需要的时候让程序抛出异常了。很多时候,系统是否要引发异
常,可能需要根据应用的业务需求来决定,如果程序中的数据、执行与既定的业务需求不符,这
就是一种异常。由于与业务需求不符而产生的异常,必须由程序员来决定引发,系统无法引发这
种异常。

raise的基本语法为:
raise [exceptionName [(reason)]]

其中用 [] 括起来的为可选参数,其作用是指定抛出的异常名称,以及异常信息的相关描述。如果
可选参数全部省略,则 raise 会把当前错误原样抛出;如果仅省略 (reason),则在抛出异常时,
将不附带任何的异常描述信息。

也就是说,raise 语句有如下三种常用的用法:
1.raise:单独一个 raise。该语句引发当前上下文中捕获的异常(比如在 except 块中), 或默认引发
              RuntimeError 异常。
2.raise 异常类名称:raise 后带一个异常类名称。该语句引发指定异常类的默认实例。
3.raise 异常类名称(描述信息):在引发指定异常的同时,附带异常的描述信息。

上面三种用法最终都是要引发一个异常实例(即使指定的是异常类,实际上也是引发该类的默认实
例),raise 语句每次只能引发一个异常实例。举个例子:

def get_age():
    a = int(input('请输入年龄:'))
    if a < 0:
        raise ValueError('年龄过大!')
    elif a > 120:
        raise ValueError('年龄过小!')
    else:
        return a

try:
    age = get_age()
except ValueError as e:
    print('出现错误,错误类型是:', e)
    age = 0

print('年龄是:', age)

这个程序中,我们自定义了ValueError,即在输入的年龄太大或者太小时就会抛出我们自定义的“年
龄过大”和“年龄过小”异常。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值