常州网站建设公司信息谷歌推广代理公司
文章目录
- with语句
- 自定义对象支持with
- contextlib模块
- closing自动关闭
- suppress回避错误
- ExitStack清理
Python 中的 with 语句用于清理工作,封装了
try…except…finally
编码范式,提高了易用性。
with语句
with语句有助于简化资源管理:
# 离开作用域时,自动关闭文件
with open('hello.txt', 'w') as f:f.write('hello, world!')
自定义对象支持with
类只要实现上下文管理器,就可获得with支持:
- 类中实现
__enter__和__exit__
方法; - 进入with语句上下文时,
__enter__
被调用以获取资源; - 离开with上下文时,
__exit__
被调用以释放资源;
class ManagedFile:def __init__(self, name):self.name = namedef __enter__(self):self.file = open(self.name, 'w')return self.filedef __exit__(self, exc_type, exc_val, exc_tb):if self.file:self.file.close()
contextlib模块
使用contextlib.contextmanager装饰器能够使函数(生成器)自动支持with语句:
- 函数要为生成器,即有yield语句;
- 将yield语句前代码当做
__enter__
执行; - 将yield语句之后代码当做
__exit__
执行; - yield返回值赋值给as后的变量;
from contextlib import contextmanager@contextmanager
def managed_file(name):try:print("open file:", name)f = open(name, 'w')yield ffinally:print("close file")f.close()with managed_file(r'D:\temp\hello.txt') as f:print("write file")f.write('hello world!')
closing自动关闭
closing装饰器封装有close的类,在离开with作用域时自动调用close方法:
from contextlib import closing
from urllib.request import urlopenwith closing(urlopen("http://www.baidu.com")) as page:# get the page
suppress回避错误
suppress(*exceptions)
可以禁止任意数目的异常:
# 文件不存在,也不会抛出异常
with suppress(FileNotFoundError):os.remove('somefile.tmp')
ExitStack清理
ExitStack可组合多个清理器,通过向栈中添加清理回调(enter_context),在离开with时统一清理:
# 在离开时,会统一关闭打开的文件(即使部分文件在打开时抛出异常)
with ExitStack() as stack:files = [stack.enter_context(open(fname)) for fname in filenames]