07-异常处理

1. python内置异常处理

单分支异常处理:try...except

单分支异常处理是当你在知道确定会出现什么异常的情况下,使用单分支异常处理。

l = ["login","register"]
for num ,i in enumerate(l,1):
    print(num,i)
try:
    num = int(input("num >>>"))
except ValueError:              # 如果except后面有具体的异常类型,那么except就只能捕获到这一种类型的异常,无法捕获其余类型的异常。
    print("请输入一个数字")

多分支异常处理:try...except...except...

从上到下报错的代码只要找到与它相同的分支,就执行这个分支中的代码,之后结束程序。

如果找不到处理和报错类型相同的错误分支,那么程序会一直向下走,直到找到与它相同的错误分支并执行分支中的代码,否则就会程序报错。

l = ["login","register"]
try:
    num = int(input("num >>>"))
    print(l[num-1])
except ValueError:
    print("请输入一个数字")
except  IndexError:
    print("只能输入1或2")

多分支合并:try...except...except...

如果用户输入的内容错误较多,而使用多个except会很麻烦,这时可以使用多分支合并。

l = ["login","register"]
try:
    num = int(input("num >>>"))
    print(l[num-1])
except (ValueError,IndexError):
    print("输入不合法")

万能异常:try...except Exception as e...

当程序整体开发完成,并测试完毕之后,才会使用万能异常。当你不知道你的程序会报什么错误的时候,可以使用万能异常。

def buy():
    print("buy")
    name
def back():
    print("back")
    [][1]
def show():
    print("show")
    1/0
def main():
    l = [("购物",buy),("退货",back),("查看",show)]
    while 1:
        for num , i in enumerate(l,1):
            print(num,i[0])
        num = int(input("num >>> "))
        print(l[num - 1])
        try:
            func = l[num - 1][1]
            func()
        except Exception as e:
            print(e)
            print("用户在选择了%s操作之后出现了不可知的异常" % l[num - 1][0])
main()
# 上述程序在执行是会发生三个异常,而用于在实际应用中,不知道用户会如何进行操作,也就不知道 会报什么异常,所以使用万能异常,来提升用户体验度。

万能异常还有另外一中写法: try...except...

def buy():
    print("buy")
    name
def back():
    print("back")
    [][1]
def show():
    print("show")
    1/0
def main():
    l = [("购物",buy),("退货",back),("查看",show)]
    while 1:
        for num , i in enumerate(l,1):
            print(num,i[0])
        num = int(input("num >>> "))
        print(l[num - 1])
        try:
            func = l[num - 1][1]
            func()
        except :
            print(e)
            print("用户在选择了%s操作之后出现了不可知的异常" % l[num - 1][0])
main()
# 这样也能在不知道具体什么异常的情况下处理异常。

多分支+万能异常:try...except...except Exception as e

万能异常要永远在程序的最下方。

def buy():
    print("buy")
    name
def back():
    print("back")
    [][1]
def show():
    print("show")
    1/0
def main():
    l = [("购物",buy),("退货",back),("查看",show)]
    while 1:
        for num , i in enumerate(l,1):
            print(num,i[0])
        try:
            num = int(input("num >>> "))
            print(l[num - 1])
            func = l[num - 1][1]
            func()
        except (ValueError,IndexError):
            print("输入不合法")
        except Exception as e:
            print(e)
            print("用户在选择了%s操作之后出现了不可知的异常" % l[num - 1][0])
main()

else分支:try...except...else...

当程序没有报错的时候执行else中的代码,当报错时执行except中的代码 块。

try:
    print("-----")
    name
except NameError:
    print("NameError")
else:
    print("*****")

finally分支

  1. 无论程序有没有报错,都会执行finally中的语句。
  2. 如果try中的代码内容最终有 return返回值,且这段代码 最终报错了,那么也会先执行finally中的代码,再去执行retrun
# 2.假设打开一个文件,在文件中取出想要的内容,找到想要的内容之后将内容返回,并关闭文件
def func():
    f = open("person_info.txt", mode="r", encoding="utf-8")
    try:
        for line in f:
            print(line)
            if line.startswith("---"):
                return line
    except Exception as e:
        print("-*------------")
        print(e)
    finally:
        print("*********")
        f.close()       # 即使try中存在return,也会先执行finally,再去执行return
func()

注意except后面能够跟上具体的报错类型,一旦跟上了具体的报错类型,那么当前的except就只能捕获跟上的报错类型的错误,不能捕获其余的异常。

主动抛出异常:raise

主动抛出异常主要用于给其他开发者使用。

当开发者认为这一段代码可能会出现报错,并且明确知道了异常的类型 ,那么就会使用raise函数,后面跟上认为会出现的错误异常,并自定义异常提示。这样就可以在代码的末尾使用except去捕获这个异常。

def index():
    try:
        a = input("输入一个数:")
        if int(a) == 0:
            raise ZeroDivisionError("a不能是0")
    except ZeroDivisionError as e:
        print(repr(e))  # 这里需要注意:要想得到我们自定义的错误提示,需要调用repr(e)
    else:
        print(10 / int(a))
index()
"""
如果输入的数字是0,那么就会触发异常捕获,抛出错误提示:ZeroDivisionError('a不能是0')
"""

2. 自定义异常

自定义异常,其关键在于自定义的异常类要继承Exception这个类。

在主逻辑代码中,我们要主动的抛出异常,抛出的异常就是我们自定义的异常类。

# 自定义异常类
class ExistsError(Exception):
    def __init__(self,code,data):
        self.code = code
        self.data = data
class PrevError(Exception):
    def __init__(self,code,data):
        self.code = code
        self.data = data

def new_func(path,prev):
    """
    去路径为path的文件中,找到前缀为prev的数据,并返回
    错误码:
        1000:成功
        1001:文件不存在
        1002:关键字为空
        1003:未知错误
    :param path:路径
    :param prev:前缀
    :return:
    """
    response = {"code":1000,"data":None}
    try:
        if not os.path.exists(path):
            raise ExistsError(1001,"文件不存在")
        if not prev:
            raise PrevError(1002,"关键字为空")
    except ExistsError as e:
        print(e.code,e.data)
    except PrevError as e:
        print(e.code,e.data)
    except Exception as e:
        print(e)
        response["code"] = "1003"
        response["data"] = "未知错误"
    return response
原文地址:https://www.cnblogs.com/Pilaoban/p/13068989.html