Python 编程指南 | 使用 with 关键字
Python with 语句的作用是在语句块执行完毕后,自动调用 with 后面表达式的 __exit__
方法。这允许我们不必显式地调用 close 方法,就可以确保资源总会被释放。with 语句可以使代码更清晰、更具可读性,简化了文件流、数据库连接等公共资源的管理。
使用 with 示例
一个最常见的例子是打开文件,使用 with 关键字,我们可以这么写:
1 | with open('file.txt') as f: |
使用 with 关键字,我们不必显式调用 f.close()
来关闭文件。with 语句会在读取文件后自动关闭该文件。
如果我们不使用 with 关键字,为了避免在读取文件的过程中出现异常,使文件不能被正常关闭,导致文件资源一直被该程序占用而无法被释放,我们需要使用 try…except…finally
编码范式,具体代码如下:
1 | try: |
在该代码示例中,我们对可能发生异常的代码处使用 try 关键字进行捕获,发生异常时执行 except 代码块,而 finally 代码块是无论什么情况都会执行,所以文件会被关闭,不会因为执行异常而导致该文件资源一直被占用。
通过对比这两个示例可以发现,使用 with 关键字的代码会更加简洁。
with 语句实现原理
with 语句对于任何实现了上下文管理协议(context management protocol)的对象都起作用。这个协议包含 __enter__
和 __exit__
两个方法。__enter__
方法在 with 块开始时被调用,并且返回一个用于该块的资源。__exit__
方法在离开 with 块时,无论是正常退出还是由于异常,都会被调用。
例如,我们可以使用上下文管理器来实现一个简单的计时器(即 with 语句来记录代码块的执行时间),观察 with 语句的执行过程。
示例代码:
1 | import time |
代码执行逻辑如下:
首先定义一个 Timer 类,它实现了
__enter__
和__exit__
方法,这使它可以作为上下文管理器使用。__enter__
方法在 with 语句开始时被调用。它记录了当前时间,用于开始计时。with 语句块运行,执行需要计时的代码。
__exit__
方法在 with 语句结束时被调用。它再次记录当前时间,并计算执行时间(end - start),然后打印出来。
总体来说,这个 Timer 类通过 __enter__
和 __exit__
两个方法来计算 with 代码块的执行时间。
(END)