文章目录
  1. 1. 引子
  2. 2. 详述
    1. 2.1. enter与exit
    2. 2.2. 上下文管理器
  3. 3. 自己的理解

都说 with 语句是 Python 中 “人生苦短,我用 Python” 的经典代表之一,它可以使得我们在编写代码的时候非常简短,且行之有效。

引子

我习惯于一边做一边学知识,这次的实际情况是想要使用代码下载一张图片,看到了三种方式,其中一种就是with…as,于是打算好好理解一下。

代码如下:

1
2
3
tmp = requests.get(src_url, timeout=2)
with open('file_name.jpg', 'wb') as file:
file.write(tmp.content)

按理说,如果现在的我拿到这个需求,我会这样写:

1
2
3
4
5
6
tmp = requests.get(src_url, timeout=2)
file = open('file_name.jpg', 'wb')
try:
file.write(tmp.content)
finally:
file.close()

区别似乎很明显了,看上去with像是python对于try的语法糖,但是还需要查资料理解一下它具体的工作方式。

以下内容主要参考了 Python之with as语句 (屌丝版)python中with和异常处理实例分析 、 官网 8. 复合语句¶ 的第5部分。

详述

enter与exit

首先with所操作的对象,必须有两个重要的方法,__enter____exit__

Python对with的处理很聪明。

紧跟with后面的语句被求值后,返回对象的enter()方法被调用,这个方法的返回值将被赋值给as后面的变量。当with后面的代码块全部被执行完之后,将调用前面返回对象的exit()方法。

上下文管理器

with 要生效,需要作用于一个上下文管理器——

打住,到底什么是上下文管理器呢?

长话短说,就是实现了__enter____exit__方法的对象。

在进入一个运行时上下文前,会先加载这两个方法以备使用。进入这个运行时上下文时,调用__enter__方法;退出该上下文前,则会调用__exit__方法。

这里的“运行时上下文”,可以简单地理解为一个提供了某些特殊配置的代码作用域。

这里有一点特殊的是,Python中文件对象本身就是一个上下文管理器,因此我们可以使用open函数作为求值的表达式。

随后调用__enter__方法,返回的对象绑定到我们指定的标识符file上。文件对象的__enter__返回文件对象自身,因此这句代码就是将打开的 file_name.jpg 文件对象绑定到了标识符file上。

紧跟着执行 with 语句块中的内容。

最后调用__exit__,退出 with 语句块。

自己的理解

似乎with语句直接跳过了异常处理,对于不关心异常的场景下,无疑大幅减少了代码量,同时还保证了程序可以正常运行不被中断。


♦ 本文固定连接:https://www.gsgundam.com/2022/2022-11-19-python-with-as-learning/

♦ 转载请注明:GSGundam 2022年11月19日发布于 GSGUNDAM砍柴工

♦ 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

♦ 原创不易,如果页面上有适合你的广告,不妨点击一下看看,支持作者。(广告来源:Google Adsense)

♦ 本文总阅读量