python异常处理

错误:没法通过其他代码进行处理的问题 语法错误、逻辑错误
异常:多指程序在执行过程中,出现未知错误,语法和逻辑都是正确的,可以通过其他代码进行处理修复

常见的系统异常

# 1、除零异常
# 1 / 0

# 2、名称异常
# print(name)

# 3、类型异常
# "1" + 2

# 4、索引异常
l = [1, 2]
# l[3]

# 键异常
dic = {"name":"yl", "age":18}
# dic["add"]

# 值异常
# int("abc")

# 属性异常
# name = "yl"
# print(name.xx)

# 迭代器异常
it = iter([1, 2])
print(next(it))
print(next(it))
# print(next(it))

# 自己定义的异常
# 继承自Exception

异常的解决

系统一开始已经内置了一些特定的应用场景,当我们写代码的过程当中,一旦触发了这个场景,系统内部就会自动向外界抛出这个场景,也就是所谓的异常不去处理这个异常,就是程序被终止执行,导致软件的崩溃

  • 预防
    添加容错代码,容错代码过多,会造成代码混乱,主业务不清晰
  • 捕捉异常
# try:
#     print(name)  # 可能出现异常的代码
# except NameError:  # 你要捕捉异常的类别
#     print("名称有问题,请仔细检查")  # 对异常处理
# else:
#     # 没有出现异常的处理
# finally:
#     # 不管有没有出现异常都会执行的代码
try:
    1 / 0
    print(name)  # 从上往下检测,先检测先处理
except ZeroDivisionError as ze:
    print("除零错误:", ze)
except NameError as ne:
    print("名称错误:", ne)
finally:
    print("不管有没有出现异常都会执行的代码")

# 合并处理多个异常
    try:
        1 / 0
        print(name)  # 从上往下检测,先检测先处理
    except (ZeroDivisionError, NameError):
        print("异常")
    finally:
        print("不管有没有出现异常都会执行的代码")

try:
    1 / 0
    print(name) # 从上往下检测,先检测先处理
except Exception as e:
    print("异常", e)
finally:
    print("不管有没有出现异常都会执行的代码")

# with语句
# 适用于执行某段代码A之前,进行预处理,执行代码A结束之后,进行清理操作
# 文件读取的正常步骤:打开、读取、关闭
# 要保证,不管读取文件操作有没有异常,都要关闭文件
# try:
#     打开文件
#     读取文件
# finally:
#     关闭文件

# 上述过于繁琐
try:
    f = open("resouce/JPG/IMG_9327.JPG", "r")  # 应该以二进制文件读取"rb"
    f.readlines()
except Exception as e:
    print("异常提示", e)
finally:
    print("xxx")
    f.close()
# 方案二
with open("resouce/JPG/IMG_9327.JPG", "r") as f:
   f.readlines()
# 自定义上下文管理器
class Test:
    def __enter__(self):
        print("enter")
        return "xxxx"
    def __exit__(self, exc_type, exc_val, exc_tb):
        print(self, exc_type, exc_val, exc_tb)
        print("exit")
with Test() as x:  # 先enter -> body -> exit
    # x是enter方法执行的返回值
    print("body", x)  # x:"xxxx"
  • contextlib模块
    @contextlib.contextmanager 通过一个装饰器让生成器快速变成一个上下文管理器
# 生成器
# 让生成器通过一个装饰器快速变成一个上下文管理器
import contextlib
@contextlib.contextmanager  # 上下文管理器有进有出,有返回值
contextlib.closing快速让拥有close()方法的对象变成上下文管理器
def test():
    print(1)  # yield前面当作enter
    yield "xxx"
    print(2)  # yield后面当作exit
with test() as x:
    print(3, x)  # 当作中间部分

# 把主要业务逻辑部分和异常处理部分进行分离
@contextlib.contextmanager
def ze():
    try:
        yield
    except ZeroDivisionError as e:
        print("error:", e)
x = 1
y = 0
with ze():  # 上下文管理器,先yield上面try->x/y->yield下面exception
    x / y

class test:
    def t(self):
        print("tttt")
    def close(self):
        print("资源释放")
    def __enter__(self):
        return  self
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()
with test() as t_obj:  # t是enter方法返回值,恰恰是对象本身
    t_obj.t()

class test:
    def t(self):
        print("tttt")
    def close(self):
        print("资源释放")


# contextlib.closing快速让拥有close()方法的对象变成上下文管理器
with contextlib.closing(test()) as t_obj:  # t是enter方法返回值,恰恰是对象本身
    t_obj.t()
  • 手动抛出异常
# 手动抛出异常
# 通过raise语句直接抛出异常
def setAge(age):
    if age <= 0 or age >= 20:
        # print("error")
        raise ValueError("值错误")
    else:
        print("设置年龄", age)
  • 自定义异常
# 自定义异常
class LessZero(Exception): # 继承Exception
    def __init__(self, msg, error_code):
        self.msg = msg
        self.ec = error_code
    def __str__(self):
        return self.msg + str(self.ec)
        pass
def setAge(age):
    if age <= 0 or age >= 20:
        # print("error")
        raise LessZero("值错误", 404)
    else:
        print("设置年龄", age)
try:
    setAge(-90)
except LessZero as l:
    print("x", l)


你可能感兴趣的:(python学习)