上下文管理器
- 是一个对象
- 这个对象有两个特殊的方法 __enter__() 和 __exit__()
- 通过 with 语句调用这个对象时,能自动执行两个特殊方法进入和退出对象,代码非常简洁、方便
- 一般这样写:with 对象 as 标识符:
1、首先得了解一下异常处理
前面文章讲解过,详细可以点击【异常处理的四种方法,不只是try】文章
异常 try
try: f = open('file.txt', 'r') print(f.read()) # 返回:文本内容finally: f.close()
2、with 语句:可以替代 try ... finally ... 语句,使代码更简洁
用 with 语句代替 try 的写法
with open('file.txt', 'r') as f: print(f.read()) # 返回:文本内容
说 with 语句执行过程前,需要了解两个类的特殊方法,详细了解可点击【类的特殊方法,自动调用】
特殊方法说明
- 以下两个方法只能同时使用,只用做 with 语句才会自动调用
- 自动调用,无需我们自己编写
特殊方法理解
- __enter__:此方法的返回值是上下文管理器对象,会绑定到 as 子句中的标识符 f
- __exit__:关闭上下文管理器对象,需不需要抛出错误,由返回值决定
说一下 with语句 的执行过程
程序遇到 with 就判定后面是一个上下文管理器
此例中打开 file.txt 文件作为一个上下文管理器对象
- 对 open('file.txt', 'r', encoding='utf8') 求值,获得一个上下文管理器对象
- 调用上下文管理器的 __enter__ 方法,并把对象赋值给 as 子句中的标识符 f
- 执行语句块 print(f.read())
- 调用上下文管理器的 __exit__ 方法,关闭上下文管理器对象 f
3、自定义上下文管理器-通过类来实现
需要在类中自定义手动实现 __enter__ 和 __exit__ 方法
__enter__() 定义方法:返回self(对象本身),不返回无法执行 drink 方法;返回其他对象,执行其他对象的方法
__exit__() 定义方法:不返回 ,程序会正常报代码错误;返回 False,程序会正常报代码错误;返回 True,程序会忽略代码错误
下面看三个示例
示例一:__exit__()不返回值
代码正常报错
示例二:__exit__()返回值 False
代码正常报错
示例三:__exit__()返回值 True
代码不报错
总结:自定义上下文管理器,类的实现方式
- __enter__() 方法,必须返回 self或者其他对象,不返回的话 with ... as f: f 的值为 None,f 无法执行对象方法,就没有什么意义了
- __exit__() 方法,不返回值,对于代码报错,程序会自动报错
- __exit__() 方法,返回 False,对于代码报错,程序会自动报错
- __exit__() 方法,返回 True,对于代码报错,程序不报错,正常执行,所以返回 True 时要特别注意
4、自定义上下文管理器-通过函数来实现
需要用装饰器和生成器函数
两种情况:finally中没有 return;finally中有 return
from contextlib import contextmanager # python内置模块
示例一:contextlib装饰器,finally 中不返回
示例二:contextlib装饰器,finally 中返回 True、False、空、其他
代码不报错
总结:自定义上下文管理器,函数的实现方式
- 需要 contextmanager 装饰器
- 需要一个生成器,yield 返回对象
- yield 要用try ... finally 语句包裹,不然对象报错,后面不执行
- finally 语句不返回值,代码正常报错
- finally 语句有返回,代码不报错
喜欢的小伙伴,请关注 python一看便懂。