既然需要异常处理,那么就需要知道什么时候容易出现异常,
当内容不确定的时候容易出现异常,例如:有用户参与进行交互,或者有外界的数据,文件中或是网络上
当嵌套调用的过程中内部出现问题时,外部调用的部分都会报错.
python标准异常移步→菜鸟
异常处理
单分支
# except处理的异常必须和实际报错的异常是相同的 try: num = int(input('num >>>')) except ValueError: print('请输入一个数字')
多分支
try: num = int(input('num >>>')) print(l[num - 1]) # 从上向下报错的代码只要找到一个和报错类型相符的分支就执行这个分支中的代码,然后直接退出分支 except ValueError: print('请输入一个数字') # 如果找不到能处理和报错类型相同的分支,会一直往下走,最后还是没有找到就会报错 except IndexError: print('只能输入1或2')
多分支合并
try: num = int(input('num >>>')) print(l[num - 1]) except (ValueError, IndexError): print('您输入的内容不合法')
万能异常
try: func = l[num - 1][1] func() except Exception: print('发生了不可知的异常')
as语法可以将具体错误打印出来
try: func = l[num - 1][1] func() except Exception as e: print(e) print(e.args,e.__traceback__.tb_lineno,e.__traceback__.tb_frame) print('用户在选择了%s操作之后发生了不可知的异常' )
# try + except相当于万能异常 try: int('aaa') except: print(123)
注意:当多分支与万能异常同时使用时,万能异常必须在多分支异常的下面
finally与else
try: print('aaa') # 给某某某发邮件 name # [][1] # 1/0 except NameError: # 网络不稳定,邮箱地址错误 print('name error') except IndexError: print('index error') except Exception as e: print('Exception') else: # 当try中的代码不发生异常的时候 走else分支 如果发送成功了 进行一些处理 print('else') finally: # 无论如何都会被执行 print('finally')
注:当try中的代码不发生异常的时候 走else分支 如果发送成功了 进行一些处理,finally无论如何都会被执行,且就算是return也会先执行finally,即使是报错程序结束,也会在结束前执行finally代码
主动抛出异常
raise ValueError
自定义异常
class MyException(Exception): def __init__(self, name, msg): self.name = name self.msg = msg try: raise MyException("这是", "自定义异常") except MyException as obj: print(obj.name, obj.msg)
断言
assert 1==2 # 只能接受一个布尔值
异常处理
用if方式
def func(path, prev): """ 去path路径的文件中,找到前缀为prev的一行数据,获取数据并返回给调用者。 1000,成功 1001,文件不存在 1002,关键字为空 1003,未知错误 ... :return: """ respond = {"code": 1000, "word": None} try: if not os.path.exists(path): respond["code"] = 1001 respond["word"] = "文件不存在" if not prev: respond["code"] = 1002 respond["word"] = "关键字为空" except Exception: respond["code"] = 1003 respond["word"] = "未知错误" return respond
用对象
import os class ExistsError(Exception): def __init__(self, num, name): self.num = num self.name = name class KeyInvalidError(Exception): def __init__(self, num, name): self.num = num self.name = name def new_func(path, prev): """ 去path路径的文件中,找到前缀为prev的一行数据,获取数据并返回给调用者。 1000,成功 1001,文件不存在 1002,关键字为空 1003,未知错误 ... :return: """ response = {'code': 1000, 'data': None} try: if not os.path.exists(path): raise ExistsError(1001, "文件不存在") if not prev: raise KeyInvalidError(1002, "关键字为空") pass except ExistsError as obj: response['code'] = obj.num response['data'] = obj.name except KeyInvalidError as obj: response['code'] = obj.num response['data'] = obj.name except Exception: response['code'] = 1003 response['data'] = '未知错误' return response
获取异常的堆栈信息
import trance try: … except Exception as e: trance.format_exc()