With是一段
try…except…finally
代码块
With的主要设计初衷和应用场景是用于异常处理,尤其是涉及资源申请和释放的场景。本质上,With是一段try…except…finally
代码块,但应用起来要比try…except…finally
干净优雅,所以会在Python程序中大量使用。假设有如下一段标准的异常处理代码块:
file = open('./test_runoob.txt', 'w')
try:
file.write('hello world')
finally:
file.close()
使用With关键字会简化为:
with open('./test_runoob.txt', 'w') as file:
file.write('hello world !')
With之所以能简化try…except…finally
代码也没有什么特别的“秘密”,实际上它需要被操作的类“配合”才行,简单说就是实现__enter__
和__exit__
两个方法,而实现了这两个方法的类也被称之为上下文管理器
(Context Manager
)。这两个方法是Python众多“魔法函数”中的两个,专门用于构建上下文管理器, 关于魔法函数我们会在专门的文章中介绍。
With配合上下文管理器,可以完成更多“奇妙”的工作
上下文管理拥有非常广泛的应用场景,远远不限于资源申请和释放,通过上下文管理器,可以完成更多“巧妙”的工作。一个典型的例子就是在Airflow中通过With构建DAG时,不必显示地将Operator添加到DAG中,只要是在With语句块内声明的Operator,都会被自动添加到DAG中,这省去了大量冗余的addOperator操作。关于Airflow是如何实现这一效果的,请参考此文:Python笔记 · Airflow中的DAG与With语法
参考:
https://www.runoob.com/python3/python-with.html
https://marclamberti.com/blog/apache-airflow-with-statement/