Python异常处理

Python异常处理

一.前言

基本上各个语言都会有针对异常的处理。足以体现出异常处理的重要性。异常处理的重要性往往体现在了后期的维护上。对于开发者而言,如果一段代码有try-catch-finally这样的语句,那么在抛异常的时候,开发者就会很容易定位导致系统出bug的位置,大大节省了代码维护的时间。同时,当一个产品发布出去的时候,如果用户非法输入某些东西,而你的代码里面拥有完善的异常处理机制,那么,开发者就可以通过抛出异常的位置,迅速定位,这对于产品迭代,功能增加,以及增加代码的健壮性都有着很重要的意义(可以大大缩短找bug的时间)

二.错误VS异常

对于新手来说,可能很容易就对这两个概念产生混淆。但实际上,这两个概念是有差别的。

1.错误

错误大致分为三个:

  • 语法错误:比如说,你想定义一个类,结果你把class写成了case(即:拼写错误)。不过,这种错误,往往通过你的开发工具就可以很轻易的找出来
  • 逻辑错误:代码逻辑有问题,比如说一个60多岁的人,你在程序中把人家定义为“婴儿”,这显然是荒谬的。这种往往就是开发者的主观原因造成的。
  • 其他错误。

2.异常

异常一般是指:逻辑和语法都没问题,但是程序在执行过程当中还是出问题了。这种问题往往很隐蔽,很多时候会让人觉得莫名其妙。比如说,你写了这么一个代码:

age = input("请输入年龄")
if age > 60:
    print("老年人")

上面这段代码本身没问题,但是如果用户不讲究武德,直接给你输入:qwert。那么这个是一个字符串,根本就不是一个数字,那么就会导致程序出问题。

本篇文章既然要说异常处理,那么主要就是针对异常来说事。

三.常见的系统异常

1.异常分类

异常名称示例
除零异常ZeroDivisionError2/0
名称异常NameError前面定义了一个name,然后写后续代码的时候协程了nmae
类型异常TypeError“abc” + 2
索引异常IndexErrora = [1,2,3,4]
b=a[6]
键值异常KeyErrora = {“name”:“Wang”, “age”:20}
a[“sex”]
值异常ValueErrorint(“a”)
属性异常AttributeError一个类里面没有某个属性,但是类对象却去调用
迭代器异常StopIterationit = iter([1, 2])
print(next(it))
print(next(it))
print(next(it))

2. 系统异常的继承关系

首先,在Python当中,所有的异常都是以BaseException作为父类的,那么通过BaseException往下继承,又可以大致分为四个大类:

  • SystemExit:由sys.exit()函数引发。当它不处理时,Python 解释器退出

  • KeyboardInterrupt:这个是由用户通过键盘手动退出

  • GeneratorExit:当用户关闭generator的时候(generator.close())的时候触发

  • Exception:所有内置的、 非系统退出异常是从该类派生的。如果用户想要自定义一个异常处理,那么都是要继承这里面的各种异常。这个是一个很庞大的类,大体情况如下:

在这里插入图片描述

四.异常处理

1. try-except-else语句

这个是最为常用的一个语句,其中except可以有多个,它的语法结构如下:

try:
	本来需要执行的逻辑
except 异常类1:
	异常类1发生的时候,要执行的东西
except 异常类2:
	异常类2发生的时候,需要执行的东西
else:
	没有发生异常的时候,需要执行的东西

举个例子:

try:
    fp = open("test.txt", "w")
    fp.write("test")
except IOError:
    print("Error: 没有找到文件或读取文件失败")
else:
    print("写入成功")
    fp.close()

注意try-except-else的一些要点:

  • 如果当try后的语句执行时发生异常,如果这个异常正好是except语句当中有的,那么执行except当中的语句,当该异常处理完毕后,控制流就通过整个try语句。
  • 如果在try后的语句里发生了异常,而这个异常却没有在except语句当中做处理,那么该异常就会递交到上层的try,或者到程序的最上层(这样将结束程序,并打印默认的出错信息)。

注意,一个except语句当中,你可以写多个异常类:

def convert_to_num(var):
    try:
        return int(var)
    except ValueError, Argument:
        print("参数没有包含数字\n", Argument)

# 调用函数
convert_to_num("xyz");

2.try-finally

这个语句有一个重要特点:当退出try语句的时候,总会执行finally当中的内容(不管是否出现异常,都会执行finally)

try:
    fp = open("test.txt", "w")
    try:
        fp.write("test")
    finally:
        print("关闭文件")
        fp.close()
except IOError:
    print("Error: 没有找到文件或读取文件失败")

如果进入try之后,有异常,那么就会立刻执行finally当中的内容,然后,开始执行except语句

3.raise语句

这个raise语句,是用来触发异常的。raise语句的语法如下:

raise [exceptionName [(reason)]]

其中,用 [] 括起来的为可选参数,exceptionName为触发的异常类型,而reason则是为这个异常添加描述信息。如果可选参数全部省略,则 raise 会把当前错误原样抛出;如果仅省略 (reason),则在抛出异常时,将不附带任何的异常描述信息。

def myLevel( level ):
    if level < 1:
        raise Exception,"Invalid level!"
        # 触发异常后,后面的代码就不会再执行
try:
    myLevel(0)           
except Exception,err:
    print(1,err)
else:
    print(2)

输出结果:

Invalid level!

五.自定义异常

作为编程人员,可以定义一个类,同时在构造函数(即:__init()__函数)当中进行类的初始化。用这种方式来自定义一个异常。

class MyException(RuntimeError): # 基于RuntimeError,所以继承RuntimeError
    def __init__(self, arg):
        self.args = arg
        
try:
    raise MyException("my Exception") # 触发异常
except Networkerror,e:
    print e.args
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值