异常处理

一、什么是异常处理

  • 程序中的两种异常:

    • 1、语法错误: 空格 缩进以及其他语法规则(一般在语法检测的时候就会报错)
    • 2、逻辑错误:程序整体能编译,但是在运行时,因具体的逻辑出现问题,例如:input的内容转int
    • 3、异常就是程序运行时发生错误的信号,在Python中,错误触发的异常如下:异常发生后后面的代码不执行。

img

  • 在python中不同异常可以用不同的类型去标识(python将同一类型的错误类型进行统一),不同的类对象标识不同的异常。

     
     
     
    x
     
     
     
     
                                               常见异常
                                               
    AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
    IOError 输入/输出异常;基本上是无法打开文件
    ImportError 无法引入模块或包;基本上是路径问题或名称错误
    IndentationError 语法错误(的子类) ;代码没有正确对齐
    IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
    KeyError 试图访问字典里不存在的键
    KeyboardInterrupt        Ctrl+C被按下
    NameError 使用一个还未被赋予对象的变量
    SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
    TypeError     传入对象类型与要求的不符合
    UnboundLocalError     试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
    导致你以为正在访问它
    ValueError 传入一个调用者不期望的值,即使值的类型是正确的
     
  • Python中常见的异常类:

    • BaseException # 所以异常的基类
    • SystemExit # 解释器请求退出
    • KeyboardInterrupt # 用户中断执行(^C)
    • Exception # 常规错误的基类
    • Stoplteration # 迭代器没有更多值……
  • 异常处理:通过捕捉异常,使程序进入另一个处理分支,执行特定的逻辑,使程序不崩溃

  • 异常处理的目的:提高用户体验,提高代码的容错性

  • 为什么要进行异常处理:检测到了一个错误时,触发异常,异常触发后且没被处理的情况下,程序就在当前异常处终止,后面的代码不会运行,谁会去用一个运行着突然就崩溃的软件。

    image.png

二、如何进行异常处理

  • 1、if判断式: 最常见的if语句只是针对一行代码,如果有多行需要使用多个if判断式

  • 2、python为每一种异常定制了一个类型,提供特定的语法结构:

    • 1、try …… except……

       
       
       
      xxxxxxxxxx
       
       
       
       
      try:
           被检测的代码块
      except 异常类型:
           try中一旦检测到异常,就执行这个位置的逻辑
      #1    
      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()    
      
      
      #2
      s1 = 'hello'
      try:
          int(s1)
      # except IndexError as e:   # 如果捕捉不到相应的异常则报错
      except ValueError as e:
          print (e)  #invalid literal for int() with base 10: 'hello'
       
  • 多分支:

     
     
     
    xxxxxxxxxx
     
     
     
     
    # try……except……except……
    s1 = 'hello'
    try:
        int(s1)
    except IndexError as e:
        print(e)
    except KeyError as e:
        print(e)
    except ValueError as e:
        print(e)
       
    #万能异常 Exception,他可以捕获任意异常
    s1 = 'hello'
    try:
        int(s1)
    except Exception as e:  #e是异常的报错信息
        print(e)
        
    #如果你统一用Exception,没错,是可以捕捉所有异常,但意味着你在处理所有异常时都使用同一个逻辑去处理(这里说的逻辑即当前expect下面跟的代码块,如果你想要的效果是,对于不同的异常我们需要定制不同的处理逻辑,那就需要用到多分支了
    #try……except……else……
    try:
        choose = int(input('请输入您想选择的商品序号 :'))
        print(l[choose-1])
    except (ValueError,IndexError) as e1:  #这里括号里可以写一类操作后出现的报错,以便做同样的处理逻辑
        print(e1)
        print('请输入一个正常的序号')
    except Exception as e2:  #如果上面异常被捕获就跳过
        print(e2)
    else:
        print('执行我啦')
        
    # else: 如果try中的代码顺利的执行完,没有报错,那么就执行else中的代码是用来汇报整个try中的代码执行成功用的
    # 一般情况下 else中的内容都是安全的不会有报错隐患,用于打印,区分在报错代码下一行执行
    #try……except……except……finally……      try……finally……
    def func(filename):
        try:
            f = open(filename,'r')
            content = f.read()
            return content
        except Exception as e:
            print(e)
        finally:        # 无论如何都要执行  用于一些必要的收尾工作
            f.close()
            print('一定会执行')
    ret = func('test') 
    print(ret)   #一定会执行   wjhal
    # finally : 必须执行
        # 遇到return也先执行finally中的代码  ***
        # 遇到报错也在程序结束之前先执行finally中的代码 ***
        
    #列题
    def wrapper(func):
        def inner(*args,**kwargs):
            try:
                print('before func')
                return func(*args,**kwargs)  # 在return之前还是会执行finally
            finally:
                print('after func')
        return inner
    @wrapper
    def func():
        print('在 func中') 
    func()   #结果 before func  在 func中   after func
     
  • 主动抛异常

    • raise 异常名称('打印信息') 一般结合自定义异常类使用,下文讲

       
       
       
      xxxxxxxxxx
       
       
       
       
      raise ValueError('类型错误')  # ValueError: 类型错误
      class Empty(Exception):
          def __init__(self,msg):
              self.msg = msg
              super().__init__()
          def __str__(self):
              return self.msg
         
      raise Empty('我报错了!')  #__main__.Empty: 我报错了!
      #2
      class Empty(Exception):  #自定义类
          def __init__(self,msg):
              self.msg = msg
              super().__init__()
          def __str__(self):
              return self.msg
          
      class 班级:
          def __init__(self):
              self.students = ['赵大宝']
          def get(self):
              if not self.students:
                  raise Empty('学生列表已为空')
              else:
                  return self.students.pop()
      clas = 班级()
      stu1 = clas.get()
      print(stu1)   #赵大宝
      stu2 = clas.get()
      print(stu2)  #__main__.Empty: 学生列表已为空
       
  • 断言:Python的断言就是检测一个条件,如果条件为真,它什么都不做;反之它触发一个带可选错误信息的AssertionError。

     
     
     
    xxxxxxxxxx
     
     
     
     
    #1、
    assert 1 == 5,'1 不等于 5 在报错时打印这段话'    #AssertionError: 1 不等于 5 在报错时打印这段话
    #2、unittest常用的断言方法:
        1.assertEqual(self, first, second, msg=None)
        --判断两个参数相等:first == second
        2.assertNotEqual(self, first, second, msg=None)
        --判断两个参数不相等:first = second
        3.assertIn(self, member, container, msg=None)
        --判断是字符串是否包含:member in container
        4.assertNotIn(self, member, container, msg=None)
        --判断是字符串是否不包含:member not in container
        5.assertTrue(self, expr, msg=None)
        --判断是否为真:expr is True
        6.assertFalse(self, expr, msg=None)
        --判断是否为假:expr is False
        7.assertIsNone(self, obj, msg=None)
        --判断是否为None:obj is None
        8.assertIsNotNone(self, obj, msg=None)
     
  • 自定义异常

     
     
     
    xxxxxxxxxx
     
     
     
     
    class EvaException(BaseException):
        def __init__(self,msg):
            self.msg=msg
        def __str__(self):
            return self.msg
    try:
        raise EvaException('类型错误')
    except EvaException as e:
        print(e)  #类型错误
     

     

posted @ 2019-04-05 15:19  独角兕大王  阅读(257)  评论(0编辑  收藏  举报