异常处理

异常处理

我们知道,程序总会出现各种异常,出现异常,我们就应该去排查,去处理,使之良好地运行,程序的异常分为两类,一类是语法错误,这个比较低级,应该杜绝,各大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

 

posted @ 2019-01-19 22:26  乘月归  阅读(227)  评论(0编辑  收藏  举报