zoukankan      html  css  js  c++  java
  • 异常处理

    异常处理

    我们知道,程序总会出现各种异常,出现异常,我们就应该去排查,去处理,使之良好地运行,程序的异常分为两类,一类是语法错误,这个比较低级,应该杜绝,各大IDE都有语法检测,写代码时出现飘红就应该想办法解决;另一类是逻辑错误,比如将一个字符串与整型相加,这种异常需要分情况加以处理

    1. 利用if...else...分支解决

    # 提示用户输入1~10的数字
    num = input("输入选项:").strip()
    
    if num.isdigit():
        num = int(num)
        if 1 <= num <= 10:
            pass
        else:
            print("请输入1~10的数字")
    else:
        print("请输入数字")

    这种方式适用于分支少、层次简单的情况,如果分支很多或者有很多嵌套就会显得很臃肿,这时就需要第二种解决方式了

    2. 利用try...except...捕获异常

    在这之前我们先来看一下如果不用 if...else...分支会出现什么异常

    num = input("输入选项:").strip()
    num = int(num)
    输入选项:abc
    Traceback (most recent call last):
      File "D:/异常处理.py", line 32, in <module>
        num = int(num)
    ValueError: invalid literal for int() with base 10: 'abc'

    从报错信息里可以看到出现了ValueError,因此我们可以通过捕获这个异常,然后根据这个异常进行某些操作

    1 lst = ["", "", "", ""]
    2 num = input("输入选项:").strip()
    3 try:
    4     num = int(num)
    5     print(lst[num])
    6 except ValueError:   # 输入的不是数字时,捕获这个异常
    7     print("请输入数字")
    8 except IndexError:   # 输入的数字范围不对时,捕获这个异常
    9     print("请输入0~3之间的数字")

    上面的就是try...except...的多分支结构,单分支结构比它还简单,就是只有一个except分支,就不多介绍了

    这里有一个小知识点:捕获异常的内容(不是名字)

    1 lst = ["", "", "", ""]
    2 num = input("输入选项:").strip()
    3 try:
    4     num = int(num)
    5     print(lst[num])
    6 except ValueError as e:
    7     print(e)       # invalid literal for int() with base 10: 'abc'
    8 except IndexError as e:
    9     print(e)       # list index out of range

    不知道会出现什么异常时,可以使用exception来表示所有异常

    1 lst = ["", "", "", ""]
    2 num = input("输入选项:").strip()
    3 try:
    4     num = int(num)
    5     print(lst[num])
    6 except Exception as e:
    7     print(e)

    try...except...也可以嵌套,不过不建议使用

     1 lst = ["", "", "", ""]
     2 num = input("输入选项:").strip()
     3 try:
     4     num = int(num)
     5     try:
     6         print(lst[num])
     7     except IndexError:
     8         print("请输入0~3的数字")
     9 except ValueError:
    10     print("请输入数字")

    这里有一个小知识点:try...会在捕捉到第一个异常时就停止,然后执行except...的语句

    lst = ["", "", "", ""]
    num = input("输入选项:").strip()    
    try:
        print(111)
        num = int(num)
        print(222)
    except Exception as e:
        print(e)
    
    输入选项:abc
    111
    invalid literal for int() with base 10: 'abc'

    使用try...except...时,要根据具体情况选用合适的结构:

    (1)当不关心异常信息,只是想跳过异常执行某些操作(退出等)时,使用try...except Exception...

    (2)当需要根据异常的种类而执行不同的分支语句时,用try...except...的多分支结构较好

    (3)大多数情况使用多分支加try...except Exception...

    lst = ["", "", "", ""]
    dic = {1: "", 2: ""}
    num = input("输入选项:").strip()
    try:
        num = int(num)
        print(lst[num])
        print(dic[num])
        for k in dic:
            del dic[k]
    except IndexError as e:
        print(e)
    except KeyError as e:
        print(e)
    except Exception as e:
        print(e)

    执行结果

    输入选项:2
    世
    药
    dictionary changed size during iteration

     try...except...还可以与else连用,表示没有捕获到异常就执行else后面的语句

     1 lst = ["", "", "", ""]
     2 num = input("输入选项:").strip()
     3 try:
     4     num = int(num)
     5     print(lst[num])
     6 except Exception as e:
     7     print(e)
     8 
     9 else:
    10     print("一切都在掌握中...")

     try...except...还可以与finally连用,表示有没有异常都执行finally后面的语句,这有什么用呢?做一些保存工作,比如关闭文件句柄、数据库连接等

    # test.json
    {"1": "小王子", "2": "朝闻道"}
    
    import json
    try:
        f1 = open("test.json", encoding="utf-8", mode="r")
        dic = json.load(f1)
        print(dic["2"])
    except KeyError as e:
        print(e)
    except Exception as e:
        print(e)
    finally:
        f1.close()
        print("in finally")
    
    try:
        f1.seek(0)    # 移动光标到文件开头
        data = f1.read()   # 尝试读取文件内容,如果读取不到,就说明上面finally已经关闭了文件句柄
        print(data)
    except Exception as e:
        print(e)       # I/O operation on closed file.

    try...finally...还可以在函数结束或者循环break之前执行一段语句

    def func():
        try:
            return 666
        finally:
            print(111)
    
    
    func()   # 111
    def func():
        try:
            while True:
                break
        finally:
            print(222)
    
    
    func()   # 222

    主动抛出异常

    前面在类的约束里面已经用到过主动抛出异常,其语法为raise 异常名("异常内容")

    raise ValueError("输入的值有误")
    Traceback (most recent call last):
      File "D:/异常处理.py", line 241, in <module>
        raise ValueError("输入的值有误")
    ValueError: 输入的值有误

    自定义异常

    随着项目的扩展,有时会出现一些Python无法识别的异常,这时候就需要我们自己定义异常了

    # PhoneConnectionError是提示的异常信息,但是直接写在except里解释器识别不了,所以需要自己先定义一个类
    
    class PhoneConnectionError(BaseException):  
        pass
    
    
    try:
        raise PhoneConnectionError("连接错误")
    except PhoneC

    assert

    用来让程序测试这个condition,如果condition为false,那么raise一个AssertionError出来。逻辑上等同于:

    if not condition:
        raise AssertionError()

    assert的一般用法是:assert condition [, arguments]

    a = 1
    b = 2
    assert a == b, "a不等于b"
    Traceback (most recent call last):
      File "D:/异常处理.py", line 262, in <module>
        assert a == b, "a不等于b"
    AssertionError: a不等于b
  • 相关阅读:
    Java追加文件内容的三种方法
    3种方法关闭Java线程
    linux系统登陆过程
    swift正点
    swift简介(东拼西凑,看看就的了)
    变量设置和查看
    进程调度优先级
    获取进程对应的UID登陆用户
    进程会计
    system调用
  • 原文地址:https://www.cnblogs.com/zzliu/p/10284823.html
Copyright © 2011-2022 走看看