外观
with 语句
Python 中的with
语句用于异常处理,封装了 try...except...finally
编码范式,提高了易用性。
with
语句使代码更清晰、更具可读性, 它简化了文件流等公共资源的管理。
在处理文件对象时使用 with
关键字是一种很好的做法。
我们可以看下以下几种代码实例:
例01 普通的文件读写
f = open('test.txt', 'w')
f.write('hello world')
f.close()
以上代码如果在调用 write
的过程中,出现了异常,则 close
方法将无法被执行,因此资源就会一直被该程序占用而无法被释放,且文件更改无法被保存。为了防止这种情况,我们可以使用如下方式避免:
例02 使用 try
语句的改进
f = open('test.txt', 'w')
try:
f.write('hello world')
finally:
f.close()
以上代码我们对可能发生异常的代码处进行 try
捕获,发生异常时执行 except
代码块,finally
代码块是无论什么情况都会执行,所以文件会被关闭,不会因为执行异常而占用资源,也不会丢失文件的更改。
然而,这样的代码太过于麻烦了。对于这样的情况,Python 中有着许许多多的封装,with
语句就是其中一种。
例03 使用 with
关键字
with open('test.txt', 'w') as f:
f.write('hello world')
使用 with
关键字系统会自动调用 f.close()
方法,本例的代码和例02的代码在运行时是一模一样的。
深入理解原理
with
语句实现原理建立在上下文管理器之上。
上下文管理器是一个实现 __enter__
和 __exit__
方法的类。
使用 with
语句确保在嵌套块的末尾调用 __exit__
方法。
这个概念类似于 try...finally
块的使用。
例03 实现了将 hello world
写到 test.txt
文件中。
Python 的文件对象中定义了 __enter__
和 __exit__
方法,即文件对象也实现了上下文管理器,首先调用 __enter__
方法,然后执行 with
语句中的代码,最后调用 __exit__
方法。 即使出现错误,Python 也一定会调用 __exit__
方法,进而关闭文件流。
要自定义一个支持 with
的类,参阅上下文管理相关魔术方法(with)。