引言

  • 系统内部一开始已经内置了一些特定的错误场景,当我们触发了这个场景时,系统内部就会向外界抛出异常。如果我们没有处理,程序就会停止运行。

    解决异常

  • 通过条件判断语句在程序内部进行容错检测,避免错误的发生。缺点: 如果要处理的错误太多,会有很多的和业务逻辑无关的代码。

    捕捉异常,然后再处理

    1. try:
    2. # 可能出现异常的代码
    3. # 有异常就会抛出,不会再执行剩下的 try后面的代码
    4. except xxxError as xxx:
    5. # 出现异常后,而且被捕捉到的代码
    6. # except可以写多个,用来捕捉多个不同的异常
    7. else:
    8. # 异常未被捕捉到所执行的代码(可以省略)
    9. finally:
    10. # 不管有没有异常都会执行的代码

    异常的合并解决

    1. try:
    2. 1 / 0
    3. print(val)
    4. except (ZeroDivisionError, NameError) as e:
    5. print(e)
    6. else
    7. print("fine like this")
    8. # 执行结果:division by zero
    9. # 如果不清楚异常的具体名字,可以写 Exception进行替代

    上下文管理器

    ```python

    在主要代码的执行前后分别添加一些操作

    实现了 enter(), exit()两个函数的类产生的对象就是上下文管理器

    class Test: def enter(self):

    1. return self

    def exit(self, exc_type, exc_val, exc_tb):

    1. # exc_type: 异常类型
    2. # exc_val: 异常的值
    3. # exc_tb: 异常追踪信息
    4. # 函数有返回值,True表示异常已经处理,False表示异常还未处理
    5. print(exc_val)
    6. return True

    with Test() as x: # as 后面表示对象的enter()方法执行后的返回值 1 / 0 # 产生的异常信息将对号入座传入exit()的函数参数中

执行结果: division by zero

通过 contexlib模块,通过生成器快速产生一个上下文管理器

import contexlib

yield之前的代码相当于 enter()中的代码,但是返回结果要通过 yield来返回

yield之后的代码相当于 exit()中的代码

@contexlib.contexmanager def test(): print(1) yield “x here” print(2)

with test() as x: print(3) print(x)

执行结果:

1 3 x here 2

  1. <a name="ece39eee"></a>
  2. ## with语句
  3. ```python
  4. with open("./xx.txt", "r") as f:
  5. f.readlines()
  6. with open("a.jpg", "rb") as f1, open("b.jpg", "wb") as f2:
  7. content = f1.read()
  8. f2.write(content)

手动抛出异常

  1. # 通过 raise语句手动抛出异常
  2. # 自己设计
  3. def set_age(age):
  4. if age <= 0 or age > 150:
  5. raise ValueError("value error")
  6. print("age is %d" % age)
  7. # 给别人调用
  8. try:
  9. set_age(-18)
  10. except ValueError as e:
  11. print(e)

自定义异常

  1. # 自定义的异常要直接或间接继承自:BaseException
  2. class MyException(Exception):