• Python的异常处理


    一、什么是异常

    异常时程序发生错误的信号,程序一旦出错就会抛出异常
    在pycharm编辑器中直接编辑一个变量名x-->run

    x # 定义变量名
    异常的三个特征:1、异常的追踪信息。2、异常的类型。3、异常的内容
    # 运行结果如下: Traceback (most recent call last): # 文件的定位信息(1、异常的追踪信息) File
    "D:/pycharm/oldboy_29/day034/day034_03异常.py", line 5, in <module> # 异常发生在哪行? x # (3、异常的内容) NameError: name 'x' is not defined # 异常的种类(2、异常的类型)
    # 异常时程序发生错误的信号,程序一旦出错就会抛出异常,程序的运行随即终止,异常后的代码不会运行了
    print("异常运行前的代码")
    x
    print("异常运行后的代码")
    
    运行结果:
    异常运行前的代码
    Traceback (most recent call last):
    File "D:/pycharm/oldboy_29/day034/day034_03异常.py", line 6, in <module>
    x
    NameError: name 'x' is not defined

    二、为何处理异常

    为了增强程序的健壮性,即便是程序运行过程中出错了,也不要终止程序
    而是应该捕捉异常并处理:将出错的信息记录到日志里

    三、如何处理异常

    3.1、异常的来源

    # 1)语法上的错误(SyntaxError)
    if 1>3
        print("run...")
    
    运行结果:
      File "D:/pycharm/oldboy_29/day034/day034_03异常.py", line 17
        if 1>3
             ^
    SyntaxError: invalid syntax

    针对语法错误的处理方式一:必须在程序运行前改正。
    # 2)逻辑上的错误
    # 逻辑错误示范一
    print(x)
    运行结果:
    Traceback (most recent call last):
      File "D:/pycharm/oldboy_29/day034/day034_03异常.py", line 20, in <module>
        print(x)
    NameError: name 'x' is not defined  # 引用一个不存在的名字x
    
    # 逻辑错误示范二
    1/0
    运行结果:
    Traceback (most recent call last):
      File "D:/pycharm/oldboy_29/day034/day034_03异常.py", line 21, in <module>
        1/0
    ZeroDivisionError: division by zero   # 除数不能为0
    
    # 逻辑错误示范三
    int('abc')
    运行结果:
    Traceback (most recent call last):
      File "D:/pycharm/oldboy_29/day034/day034_03异常.py", line 22, in <module>
        int('abc')
    ValueError: invalid literal for int() with base 10: 'abc'
    
    # 逻辑错误示范四
    dic = {'name':'lsj'}
    dic['name']
    运行结果:
    Traceback (most recent call last):
      File "D:/pycharm/oldboy_29/day034/day034_03异常.py", line 24, in <module>
        dic['age']
    KeyError: 'age'  # 引用了一个不存在的key
    
    # 逻辑错误示范五
    class Foo:
        pass
    Foo.x
    运行结果:
    Traceback (most recent call last):
      File "D:/pycharm/oldboy_29/day034/day034_03异常.py", line 29, in <module>
        Foo.x
    AttributeError: type object 'Foo' has no attribute 'x'  # 引用的属性不存在

    # 逻辑错误示范六:

    # TypeError:数字类型无法与字符串类型相加
    1+’2’
    # 逻辑错误示范七:
    # ValueError:当字符串包含有非数字的值时,无法转成int类型
    num=input(">>: ") #输入hello
    int(num)
    
    # 逻辑错误示范八: # IndexError:索引超出列表的限制 l=['egon','aa'] l[3]
    # 针对逻辑错误的处理方式:有两种
    逻辑错误处理方式一
    # 方式一:错误发生的方式时可以预知的
    # 猜年龄程序为例:
    age = input('>>>:').strip() 
    age = int(age)
    if age > 18:
        print('猜大了')
    elif age < 18:
        print('猜小了')
    else:
        print('猜对了')
    
    # 运行程序时输入数字
    # >>>: 18
    # 猜对了
    
    # 程序运行时输入其他字符(这样的错误我们可以预知)
    # >>>:aaaa
    """
    Traceback (most recent call last):
      File "D:/pycharm/oldboy_29/day034/day034_03异常.py", line 38, in <module>
        age = int(age)
    ValueError: invalid literal for int() with base 10: 'aaaa'
    """
    # 猜年龄程序为例:
    age = input('>>>:').strip()  # 输入的只要不是数字就会出错,所以在逻辑上进行处理
    if age.isdigit():  # 使用if判断解决预知发生的错误
        age = int(age)
        if age > 18:
            print('猜大了')
        elif age < 18:
            print('猜小了')
        else:
            print('猜对了')
    else:
        print("必须输入数字")
    # 运行程序时输入数字
    # >>>: 18
    # 猜对了
    
    # 程序运行时输入其他字符(这样的错误我们可以预知)
    # >>>:aaaa
    # 必须输入数字
    逻辑错误处理方式二
    # 方式二:错误发生的方式时无法预知的
    """以C/S架构为例,客户端发送请求,服务端没有接收,导致程序崩溃,我们再使用if判断就无法避免异常了
    C<=============>S
    """
    # 针对无法预知的异常,我们使用try语法(全部的语法罗列)
    print('start...') try:
      # 有可能抛出异常的代码
      子代码块1
      子代码块2 # 如果此处有错误,同级后续代码不会运行,而是匹配异常类型去
      子代码块3 # 此处不能是回收资源的操作,要把回收资源的操作放进finally里,保证资源回收正常运行
    except 异常类型1 as e: # as作用是把异常的类型去一个别名给e,我们能可以再后期对这个e进行操作:打印或者记录到日志里。 pass
    except 异常类型2 as e:
      pass
    ...
    else:
      如果被检测的子代码块没有异常发生,则会执行else的子代码
    finally:
      无论被检测的子代码块有无异常发生,都会执行finally的子代码
    print('end...')
    # try语法变形一:
    try:
      子代码块1
      子代码块2
      子代码块3
    except  异常类型1 as e:  
        pass
    # try语法变形二:
    try:
      子代码块1
      子代码块2 
      子代码块3 
    finally:
      无论被检测的子代码块有无异常发生,都会执行finally的子代码
    注意:上面的做法降低了代码的可读性(所以能少用就少用)
    # 使用try来演示可预见异常
    # 用法一:
    print('start...')
    try:
        print('1111')
        l = ['aaa','bbb']
        l[3]  # 遇到异常IndexError,该行代码代码同级别的后续代码不会运行了
        print('2222')
        xxx
        print('3333')
        dic = {'a':1}
        dic['a']
    except IndexError as e:
        # print('异常已经被处理')
        print('异常的信息:',e)
    print('end...')
    运行结果:

    start...
    1111
    异常的信息: list index out of range  # 列表索引超出范围
    end...

    # 注意用法一:使用其他异常代替IndexError异常
    print('start...') try: print('1111') l = ['aaa','bbb'] l[3] # 遇到异常IndexError,该行代码代码同级别的后续代码不会运行了 print('2222') xxx print('3333') dic = {'a':1} dic['a'] # except IndexError as e: # 索引异处理 except ValueError as e: # 如果我们使用ValueError异常接收,由于代码是逐行向下运行,遇到哪个异常就报哪个异常 print('异常的信息:',e) print('end...') 运行结果: start... 1111 Traceback (most recent call last): File "D:/pycharm/oldboy_29/day034/day034_04.py", line 11, in <module> l[3] # 遇到异常IndexError,该行代码代码同级别的后续代码不会运行了 IndexError: list index out of range
    # 用法二
    print('start...')
    try:
        print('1111')
        l = ['aaa','bbb']
        # l[3]  # 遇到异常IndexError,该行代码代码同级别的后续代码不会运行了
        print('2222')
        xxx
        print('3333')
        dic = {'a':1}
        dic['a']
    except IndexError as e:  # 索引异处理
        print('异常的信息:',e)
    except NameError as e:
        print('异常的信息:', e)
    print('end...')
    运行结果

    start...
    1111
    2222
    异常的信息: name 'xxx' is not defined
    end...

    # 这里有个问题就是print('异常的信息:',e)有重复代码的出现

    # 用法三:针对多种异常的合并
    print('start...')
    try:
        print('1111')
        l = ['aaa','bbb']
        # l[3]  # 遇到异常IndexError,该行代码代码同级别的后续代码不会运行了
        print('2222')
        # xxx
        print('3333')
        dic = {'a':1}
        dic['a']
        dic['bb']
    except (IndexError,NameError) as e:  # 以元组形式加入到一行里
        print('异常的信息:',e)
    except KeyError as e:
        print('字典的key不存在:',e)
    print('end...')
    运行结果:

    start...
    1111
    2222
    3333
    字典的key不存在: 'bb'
    end...

    # 用法四:万能异常
    print('start...')
    try:
        print('1111')
        l = ['aaa','bbb']
        # l[3]  # 遇到异常IndexError,该行代码代码同级别的后续代码不会运行了
        print('2222')
        # xxx
        print('3333')
        dic = {'a':1}
        dic['a']
        dic['bb']
    # except (IndexError,NameError) as e:  # 以元组形式加入到一行里
    #     print('异常的信息:',e)
    # except KeyError as e:
    #     print('字典的key不存在:',e)
    except Exception as e:
        print('所有异常都可以匹配的到')
    print('end...')
    # 用法五:else不能与try配合使用会报语法错误
    print('start...')
    try:
        print('1111')
        l = ['aaa','bbb']
        # l[3]  # 遇到异常IndexError,该行代码代码同级别的后续代码不会运行了
        print('2222')
        # xxx
        print('3333')
        dic = {'a':1}
        dic['a']
        dic['bb']
    # except Exception as e:
    #     print('所有异常都可以匹配的到')
    else:
        print('===>')
    print('end...')
    运行结果:
      File "D:/pycharm/oldboy_29/day034/day034_05.py", line 17
        else:
        ^
    SyntaxError: invalid syntax
    # 用法六:try不能与finally配合使用
    #
    print('start...')
    try:
        print('1111')
        l = ['aaa','bbb']
        l[3]  # 遇到异常IndexError,该行代码代码同级别的后续代码不会运行了
        print('2222')
        xxx
        print('3333')
        dic = {'a':1}
        dic['a']
        dic['bb']
    finally:  # finally不处理异常,无论是否发生异常都会执行finally的子代码
        print('try与fianlly配合===>此处应该把被检测代码中回收系统资源的代码放到这里')
    print('end...')
    运行结果:

    Traceback (most recent call last):
    start...
    File "D:/pycharm/oldboy_29/day034/day034_05_01.py", line 8, in <module>
    1111
    l[3] # 遇到异常IndexError,该行代码代码同级别的后续代码不会运行了
    try与fianlly配合
    IndexError: list index out of range

     

     

     

  • 相关阅读:
    Rhythmk 一步一步学 JAVA(4):Spring3 MVC 之 Hello Word
    使用webclient同时post普通表单字段和文件表单字段数据到指定的URL【转】
    Rhythmk 一步一步学 JAVA(2) : 操作 MYSQL 数据库
    判断FLASH版本问题
    Rhythmk 一步一步学 JAVA(3): java JSON 数据序列化 以及反序列化
    Rhythmk 一步一步学 JAVA(5) Hibernate环境配置
    JS 数据存储
    文件下载 获取远程图片
    SQL SERVER 学习笔记
    AngularJS源码学习一 :directive
  • 原文地址:https://www.cnblogs.com/liunaixu/p/12898109.html
Copyright © 2020-2023  润新知