• 面向对象之异常处理


    异常处理

    1.什么是异常:

    • 代码发生错误之后,程序就中断了

    2.什么是异常处理

    • 当代码出现异常时,通过某种方式不让程序中断,合理地跳过去

    3.为什么要有异常处理

    • 增强用户体验感
    • 使代码更有健壮性,容错性

    4.异常处理的两种方式

    • if else 只能处理简单的异常,如果需要考虑的方面比较多,不适合
    • 利用try的方式进行异常处理

    5.什么时候用万能处理,什么时候用多分支

    • 如果对错误信息不关心,只是想要排除错误让程序继续运行,用万能
    • 如果对错误信息要进行明确的分流,让程序多元化开发,用分支

    6.错误分类

    • 语法错误:这种错误,根本过不了python解释器的语法检测,必须在程序执行前就改正
    • 逻辑错误

    7.具体举例分析

    7.1语法错误

    if 2 < 3            ---------不加冒号
    	print("没加冒号")
    
    dic = {"name";"alex"}    ----字典冒号换成分隔号
    

    7.2逻辑错误

    #用户输入不完整(空),或者输入不是数字,报错
    num = input("请示入数字:")
    print(int(num))
    
    dic = {"name":"海狗","age":18}
    print(dic["hobby"]) #字典的键不存在
    

    7.3异常种类

    AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
    IOError 输入/输出异常;基本上是无法打开文件
    ImportError 无法引入模块或包;基本上是路径问题或名称错误
    IndentationError 语法错误(的子类) ;代码没有正确对齐
    IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
    KeyError 试图访问字典里不存在的键
    KeyboardInterrupt Ctrl+C被按下
    NameError 使用一个还未被赋予对象的变量
    SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
    TypeError 传入对象类型与要求的不符合
    UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
    导致你以为正在访问它
    ValueError 传入一个调用者不期望的值,即使值的类型是正确的
    
    class A:
        country = "中国"
    
        def func(self):
            pass
    
    foo = A()
    print(foo.x)
    结果:AttributeError: 'A' object has no attribute 'x'
    
    print(1/0)
    结果:ZeroDivisionError: division by zero
    
    num = input("请输入数字:")
    if num.isdecimal():
        print(int(num))  #我们的正统程序放到了这里,其余的都属于异常处理范畴
    elif num.isspace():
        print("输入的是空格,执行此处")
    elif len(num) == 0:
        print("什么都没有,为空执行此处")
    else:
        print("其他错误,执行这里")
    

    7.4 if 判断处理异常

    def foo():
        print("正常运行")
    dic = {"1":foo}
    
    while True:
        choose = input("请输入数字").strip()
        if not choose or choose not in dic:
            continue
        dic[choose]()
        break
    

    7.5 异常处理的"私人订制" --try

    7.5.1 基本结构

    • try:
      	被检测的正常代码
      except 异常类型:
      	try中一旦检测到异常,就执行这个位置逻辑
      
    • f = open("text")
      g = (line.strip() for line in f)
      
      for line in g:
          print(line)
      else:
          f.close()
      
    try:
        f = open('a.txt')
        g = (line.strip() for line in f)
        print(next(g))
        print(next(g))
        print(next(g))
        print(next(g))
        print(next(g))
    except StopIteration:
        f.close()
    next(g)会触发迭代f,依次next(g)就可以读取文件的一行行内容,无论文件text有多大,同一时刻内存中只有一行内容。
    提示:g是基于文件句柄f而存在的,因而只能在next(g)抛出异常StopIteration后才可以执行f.close()
    

    7.5.2 异常类只能处理指定的异常情况

    s = "hellokity"
    try:
        int(s)  #ValueError
    except IndexError as e: #错误类型不对,报错
        print(e)
    
    try:
        num = int(input("请输入数字:"))#输入不是数字,执行except
        dic = {"name":"alex"} #只有num输入数字才执行此处
        print(dic["age"]) #执行到就报错
    except ValueError: #只捕捉num的错误
        print(666)
    

    7.5.3 多分支

    try:
        num = int(input("请输入数字:")) #输入数字才正确
        dic = {"name":"加薪"}
        print(dic["age"])  #只能捕捉,查无此键
        lst = [1,2,3]
        print(lst[11])    #索引超标
        print("只要运行到错的就执行except")
    except ValueError:
        print('输入的有非数字元素')
    except KeyError:
        print('没有此键')
    except IndexError:
        print('没有此下标')
    print(666)
    

    7.5.4 万能异常捕捉

    try:
        num = int(input("请输入数字:")) #输入数字才正确
        dic = {"name":"加薪"}
        print(dic["age"])  #只能捕捉,查无此键
        lst = [1,2,3]
        print(lst[11])    #索引超标
        print("只要运行到错的就执行except")
    except Exception as e:
        print(e)
    print(666)
    

    7.5.5 多分支 加 万能处理

    7.5.6 主动抛出异常

    try:
        raise TypeError('类型错误')
    except Exception as e:
        print(e)
    

    7.5.7 try except else finally

    try:
        dic = {"name: "加薪"}
        # print(dic['age'])
        l1 = [1, 2]
        # print(l1[100])
        print(111)
    except KeyError:
        print('没有此键')
    except IndexError:
        print('没有此下标')
    else: #有异常,不执行
        print('如果没有出现异常则执行这里')
    finally: #一定会执行
        print('finally 666')
    

    except 必须依赖于try, else必须依赖于except和try finally只是依赖于try

    try:
        dic = {"name":"加薪"}
        print(dic['age'])
        l1 = [1, 2]
        print(l1[10])
        print(111)
    finally: #执行完此句才报错
        print('finally 666')
        结果:先执行finally语句,后报错
    
    def foo():
        try:
            print(111)
            return 666
        finally:
            print(888)
    print(foo())
    #结果:111  888  666
    

    一定注意执行顺序 在return结束函数之前,执行finally代码.

    7.5.8 断言:展现一种强硬的态度

    # assert 条件
    name = "alex"
    n1 = input("请输入用户名:")
    assert name == n1  #正确执行,错误报错
    print(111)
    print(222)
    
    assert 1 == 1
    # print("断言为真")
    assert 1 != 2   #为假报错
    print("为真运行")
    

    7.5.9 自定义异常 python中给你提供的错误类型很多,但是不是全部的错误

    class AlexError(BaseException):
        def __init__(self,msg):
            self.msg = msg
    
        def __srt__(self):
            return self.msg
    
    try:
        raise AlexError("自定义错误类型") #调用__init__
    except AlexError as e:
        print(e)  #调用__str__
    
  • 相关阅读:
    P3373 【模板】线段树 2
    P3372 【模板】线段树 1
    P3368 【模板】树状数组 2
    P3374 【模板】树状数组 1
    P1004 方格取数
    P1880 [NOI1995]石子合并
    UOJ#152盘子序列
    P1886 滑动窗口
    P1440 求m区间内的最小值
    二进制中1的个数
  • 原文地址:https://www.cnblogs.com/lvweihe/p/11342351.html
Copyright © 2020-2023  润新知