zoukankan      html  css  js  c++  java
  • python中的异常处理常用方法

    异常处理

    • 什么是异常?

      异常就是与正常情况不同,程序在执行过程中出现错误,导致无法执行完毕。异常其实就是代码执行过程中出错。

    • 常见的一些异常

      • AttributeError 试图访问一个对象没有的属性,比如foo.x,但是foo没有属性x

      • IOError 输入/输出异常;无法打开文件或无法读写

      • ImportError 无法引入模块或包;基本上是路径问题或名称错误

      • SyntaxError Python语法错误异常,代码不能编译

      • IndentationError 缩进异常;代码没有正确缩进

      • IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]

      • KeyError 试图访问字典里不存在的键

      • KeyboardInterrupt Ctrl+C被按下

      • NameError 使用一个还未被赋予对象的变量

      • TypeError 传入对象类型与要求的不符合

      • UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
        导致你以为正在访问它

      • ValueError 传入一个调用者不期望的值,即使值的类型是正确的

     

    • 异常组成的三个部分

      追踪信息、异常类型、异常的值

     

    异常可以由发生的时间不同分为两类:

    1. 语法检测异常:解释器解释python语法时出现异常。必须在程序运行前改正。

    2. 运行时异常:已经通过了语法检测,在执行期间发生异常。(逻辑错误)

     

    几种不同的异常处理的语法

    1.如果错误发生的条件是可以预知的,我们需要用if进行处理:在错误发生之前进行预防

    AGE=10
    while True:
        age=input('>>: ').strip()
        if age.isdigit(): #只有在age为字符串形式的整数时,下列代码才不会出错,该条件是可预知的
            age=int(age)
            if age == AGE:
                print('you got it')
                break
            else:
                print('you are wrong')
                break
        else:
            print('请输入数字~~')

    2.如果发生的错误条件是不可以预知的,我们就需要用到try......except的几种用法:

    在错误发生之后进行处理。

    1. try.....except

      try:
      被检测的代码块
      except 异常类型:
      try中一旦检测到异常,就执行这个位置的逻辑

      #这种方式只能用来处理指定的异常情况,如果非指定异常则无法处理。如果是非指定的异常类型会直接报错。
      try:
          print('starting')
          a = int('deng')       # 这个位置很明显是有逻辑错误的
          print('ending')       # 未执行这行代码
      except ValueError:        # 检测到异常后执行了下面代码
          print('发生了ValueError') 
          
      ##
      starting
      发生了ValueError
    2. 多分枝

      try:
      被检测的代码块
      except 异常类型1:
      try中一旦检测到异常,就执行这个位置的逻辑

      except 异常类型2:
      try中一旦检测到异常,就执行这个位置的逻辑

      try:
          print('starting')
          l = []
          print(l[1])              #这个位置发生了IndexError
          int('deng')              #未执行
          print('ending')
      except ValueError:           #未执行
          print('发生了ValueError')
      except IndexError:           #检测到异常,执行下面代码
          print('发生了IndexError')
      ###
      starting
      发生了IndexError
    3. 同一分支检测多种异常

      try:

            被检测的代码块

      except(多种异常类型):

             try一旦检测到异常,就执行这个位置的逻辑

      try:
          print('starting')
          l = []
          print(l[1])        #可以看出代码到这个位置就停止了
          print('ending')
          int('deng')
      except (ValueError,IndexError):   #只要检测到异常就运行下面代码
          print('发生了ValueError')
      ###
      starting
      发生了ValueError
    4. 万能异常1

      try:

      被检测的代码块

      except Exception:

      try一旦检测到异常,就执行这个位置的逻辑

      #这种方式尽量不要用,会导致程序既不报错,也不会正常运行,无法定位报错位置。
      try:
          print('starting')
          l = []
          print(l[1])
          print('ending')
          int('deng')
      except Exception:
          print('going')
    5. 万能异常2

      try:

      被检测的代码块

      except Exception as e:

      try一旦检测到异常,就执行这个位置的逻辑

      try:
          print('starting')
          l = []
          print(l[1])
          print('ending')
          int('deng')
      except Exception as e:  #通过给异常取别名,来获取异常对象,对象中包含错误信息
          print('going')
          print(e)
          print(type(e))
      ###
      starting
      going
      list index out of range
      <class 'IndexError'>

      我们可以看到e是一个类,所有的异常类都是Exception的子类。

      万能异常与多分枝异常处理区别。

      1.如果你想要的效果是,无论出现什么异常,我们统一丢弃,或者使用同一段代码逻辑去处理他们,那么骚年,大胆的去做吧,只有一个Exception就足够了。
      2.如果你想要的效果是,对于不同的异常我们需要定制不同的处理逻辑,那就需要用到多分支了。

    6. 明确类型与万能异常2合用

      try:
      被检测的代码块
      except 异常类型1:
      try中一旦检测到异常,就执行这个位置的逻辑

      except 异常类型2:
      try中一旦检测到异常,就执行这个位置的逻辑

      except Exception as e:

      try一旦检测到异常,就执行这个位置的逻辑

      #明确类型应该放在万能类型前才能正常使用
      try:
          print('starting')
          l = []
          print(l[1])
          print('ending')
          int('deng')
      except ValueError:            
          print('值发生错误。。。')
      except ZeroDivisionError:
          print('被除数不能为0')
      except Exception as e:
          print('going')
    7. try:
      被检测的代码块
      except 异常类型1:
      try中一旦检测到异常,就执行这个位置的逻辑

      except 异常类型2:
      try中一旦检测到异常,就执行这个位置的逻辑

      except Exception as e:

      try一旦检测到异常,就执行这个位置的逻辑

      else:

      代码体中没有异常执行这个位置的逻辑

      try:
          print('starting')
          l = []
          print(l[1])
          print('ending')
          int('deng')
      except ValueError:
          print('值发生错误。。。')
      except ZeroDivisionError:
          print('被除数不能为0')
      except Exception as e:
          print('going')
      else:
          print('这段代码没有问题')
    8. try:
      被检测的代码块
      except 异常类型1:
      try中一旦检测到异常,就执行这个位置的逻辑

      except 异常类型2:
      try中一旦检测到异常,就执行这个位置的逻辑

      except Exception as e:

      try一旦检测到异常,就执行这个位置的逻辑

      else:

      代码体中没有异常执行这个位置的逻辑

      finally:

      代码体不管是否有异常,最终都执行该部分逻辑

      try:
          print('starting')
          l = []
          print(l[1])
          print('ending')
          int('deng')
      except ValueError:
          print('值发生错误。。。')
      except ZeroDivisionError:
          print('被除数不能为0')
      except Exception as e:
          print('going')
      else:
          print('这段代码没有问题')
      finally:
          print('这是备用方案~~')
          print('这是关闭文件操作')
    9. 主动触发抛出异常

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

      #自定义异常
      class LoginException(Exception):
          passdef login():
          name = input('name>>:').strip()
          pwd = input('password>>:').strip()
          if name == 'deng' and pwd == '123':
              print('login')
          else:
              raise LoginException('用户名密码错误!~')
      ​
      login()
    10. 断言 assert

      在程序中,有一段代码体,要执行必须保证某个条件必须成立,类似于if判断,但是断言不用将代码体缩进至其内部。

      #使用if判断
      l = ['ming','deng']
      if l:
          print('nihaoa ')
      #使用断言    
      assert l
      print('nihaom')
      print(l[0])

     

    总结:异常处理的作用

    1:把错误处理和真正的工作分开来
    2:代码更易组织,更清晰,复杂的工作任务更容易实现;
    3:毫无疑问,更安全了,不至于由于一些小的疏忽而使程序意外崩溃了。

  • 相关阅读:
    【LeetCode】048. Rotate Image
    【LeetCode】036. Valid Sudoku
    【LeetCode】060. Permutation Sequence
    【LeetCode】001. Two Sum
    【LeetCode】128. Longest Consecutive Sequence
    【LeetCode】081. Search in Rotated Sorted Array II
    【LeetCode】033. Search in Rotated Sorted Array
    顺时针打印矩阵
    矩形覆盖
    二维数组中的查找
  • 原文地址:https://www.cnblogs.com/5j421/p/10150432.html
Copyright © 2011-2022 走看看