跟光磊学Python开发-异常机制 跟光磊学Python开发-异常机制
异常概述
异常指的是不正常,也就是程序在执行过程中发生了不可预知的问题,导致程序崩溃。
Python中常见的异常类如下,它们都直接或者间接继承自位于builtins.py文件中的Exeption类
- NameError
- TypeError
- ValueError
- AttributeError
- SyntaxError
- IndexError
异常处理
在日常开发中应该尽量避免异常出现,而程序中可能发生异常的情况,可以通过Pyhton提供的异常处理机制来处理异常,从而提高程序的容错性。
异常处理的语法格式为
try:
可能发生异常的代码
except Exception:
当异常发生时,处理异常的代码
例如当使用字符串的index(self, sub, start=None, end=None):
方法来查找子串时,如果指定的子串找不到会抛出一个ValueError
异常
此时可以使用try/except来处理ValueError的异常,如果异常的类型不确定时可以使用Exception替换,例如这里的ValueError可以使用Exception替换,因为异常都直接或者间接继承Exception
"""
使用try/except基本异常处理
@author tony 18601767221@163.com
@version 2021-02-15 15:38:20
@since python3.9.1
"""
s = "hello"
# 使用try来尝试执行可能发生异常的代码
try:
# ValueError: substring not found
i = s.index("O")
print(i)
# 如果发生异常,那么异常信息会被except捕捉到,可以在except后面进行异常处理,如果没有发生异常,程序正常运行,而except就不会执行
except ValueError:
print("查找的子串不存在")

项目运行过程中可能会发生多个异常,此时可以将多个异常包装成一个元祖。需要注意的是同一时刻只能有一个异常发生,因为只要有一个异常发生,程序不会再往下执行,转而执行except
的异常处理的代码。
try:
可能发生异常的代码
except (异常1,异常2....)as e:
当异常发生时,处理异常的代码
其中as e表示给异常起别名
"""
多异常处理
@author tony 18601767221@163.com
@version 2021-02-15 16:09:54
@since python3.9.1
"""
try:
number / 0
except(ZeroDivisionError, NameError) as e:
print("程序出现了异常", e)
程序运行结果
而异常处理的完整语法格式,其中else和finally都是可选的,而finally通常是操作文件、数据库或者网络时关闭资源使用
try:
可能出现异常的代码
except Exception as e:
异常处理的代码
else:
没有出现异常的代码
finally:
无论是否出现异常,都会执行此语句块
异常处理之 try/except/else/finally:文件不存在异常
"""
异常处理之 try/except/else/finally
@author tony 18601767221@163.com
@version 2021-02-15 16:16:37
@since python3.9.1
"""
try:
f = None
f = open("java.txt", "r")
except Exception as e:
print("要打开的文件不存在")
print("异常信息是", e)
else:
content = f.read(1024)
print("文件内容是", end=" ")
print(content)
finally:
print("无论程序是否有异常都会执行finally")
if f != None:
print("关闭文件资源")
f.close()
程序运行结果
异常处理之 try/except/else/finally:文件存在并关闭文件资源
"""
异常处理之 try/except/else/finally
@author tony 18601767221@163.com
@version 2021-02-15 16:16:37
@since python3.9.1
"""
try:
f = None
f = open("python.txt", "r")
except Exception as e:
print("要打开的文件不存在")
print("异常信息是", e)
else:
content = f.read(1024)
print("文件内容是", end=" ")
print(content)
finally:
print("无论程序是否有异常都会执行finally")
if f != None:
print("关闭文件资源")
f.close()
程序运行结果
异常传递
当代码出现多个层级调用时,其中如果某个环节发生了异常,但是该异常没有处理,默认情况下该异常会向上抛出,如果上层也没有处理,那么会继续再向上层抛出,直到抛到解释器,解释器默认的处理方式就是中断程序,将异常信息打印输出到终端上。
"""
异常传递
@author tony 18601767221@163.com
@version 2021-02-15 15:59:32
@since python3.9.1
"""
def func_a():
print("execute func_a function")
func_b()
def func_b():
print("execute func_b function")
func_c()
def func_c():
print("execute func_c function")
result = 1 / 0
print(result)
func_a()

此时推荐在func_c()
方法处理该异常
"""
异常传递
@author tony 18601767221@163.com
@version 2021-02-15 15:59:32
@since python3.9.1
"""
def func_a():
print("execute func_a function")
func_b()
def func_b():
print("execute func_b function")
func_c()
def func_c():
print("execute func_c function")
try:
result = 1 / 0
print(result)
except ZeroDivisionError:
print("0不能作为被除数")
func_a()

当然由于异常的传递机制,也可以在func_b()
方法或者是func_a()
方法来处理异常
"""
异常传递
@author tony 18601767221@163.com
@version 2021-02-15 15:59:32
@since python3.9.1
"""
def func_a():
print("execute func_a function")
func_b()
def func_b():
print("execute func_b function")
try:
func_c()
except ZeroDivisionError:
print("0不能作为被除数")
def func_c():
print("execute func_c function")
result = 1 / 0
print(result)
func_a()
程序运行结果
自定义异常
在业务开发时需要根据对应的业务场景来自定义相关的业务异常。
自定义异常的语法格式
class 异常名Error(Exception):
pass
自定义异常
"""
定义一个手机号不是纯数字异常
"""
class PhoneNumberNotDigitError(Exception):
pass
"""
定义一个手机号长度不合法异常
"""
class PhoneNumberLengthError(Exception):
def __init__(self, msg):
self.__msg = msg
def __str__(self):
return self.__msg
pass
系统异常通常是由系统抛出,而自定义异常通常由开发人员手动抛出,其方式是 raise 异常对象
,异常对象可以是类对象,也可以是实例对象
def get_phone_number():
"""
从键盘获取用户输入的手机号,判断是否合法
:return:
"""
phone_number = input("请输入一个11位数字的手机号:")
if phone_number.isdigit() == False:
# 抛出自定义的异常 异常对象是类对象
raise PhoneNumberNotDigitError
elif len(phone_number) != 11:
# 抛出自定义异常,异常对象是实例对象
raise PhoneNumberLengthError("异常信息:手机号长度必须是11位")
return phone_number
通过导入模块调用get_phone_number()函数来处理自定义异常
"""
处理自定义异常
@author tony 18601767221@163.com
@version 2021-02-15 16:49:50
@since python3.9.1
"""
from custom_exception import *
# 处理调用get_phone_number()函数时可能发生的异常
try:
phone_number = get_phone_number()
except (PhoneNumberLengthError, PhoneNumberNotDigitError) as e:
print(e)
else:
print("你输入的手机号是", phone_number)
程序运行结果