Python with语句和__enter__、__exit__过程抽取思想
with语句的应用场景
编程中有很多操作都是配套使用的,这种配套的流程可以称为计算过程,Python语言为这种计算过程专门设计了一种结构:with语句。比如文件处理就是这类计算过程的典型代表。
使用with语句前后对比
没有使用with语句之前,我们是这样打开一个文件的:
try: # 1. [进入] f = open('a.txt', 'r', encoding="utf-8") # 2. [执行] print(f.read()) finally: if f: # 3. [退出] f.close()
python操作文件的流程一般就是这三步:
- [进入]用只读方式打开文件
如果文件不存在,open()函数就会抛出一个IOError的错误,并且给出错误码和详细的信息告诉你文件不存在 - [执行]读取文件内容
如果文件打开成功,接下来,调用read()方法可以一次读取文件的全部内容,Python把内容读到内存,用一个str对象表示 - [退出]关闭打开的文件
文件使用完毕后必须关闭,因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的
思考为什么关闭文件操作一定要放在finallly语句里?
由于文件读写时都有可能产生IOError,一旦出错,后面的f.close()就不会调用。所以,为了保证无论是否出错都能正确地关闭文件,我们可以使用try ... finally来实现。
发现共性:
我们发现其实这种过程化的语句有共性,比如说在进去一个片段
前必须做某种超赞,处理工作
后又需要执行一个结束操作。比如上面的这段代码:
finally: if f: f.close()
就可以做一个封装。
使用with语句后,我们是这样打开一个文件的:
with open("a.txt", "r", encoding="utf-8") as f: print(f.read())
这个with语句和前面的try ... finally结构是一样的,但是代码更佳简洁,并且不必调用f.close()方法。
with语句的执行原理
从解释器的角度去理解with语句执行流程。
with语句的基本形式是:
with 表达式 as 变量: 语句块
这样的一段代码可以称为一个上下文(context),在执行with语句时,解释器会先求出表达式的值,这个值(对象)是一个上下文管理器,并且这个对象拥有如下类构造方法:
def __enter__(): # 描述进入上下文的动作 pass def __exit__(): # 描述退出上下文的动作 pass
with语句在求出这个上下文管理器对象之后,自动执行
进入方法,并将这个对象的返回值赋值于 as 之后的变量,然后执行语句块。然后在退出上下文前,自动执行对象的
退出方法。
python系统和标准库的一些类型定义了这对操作,可以直接用于with语句。比如文件对象就直接支持这一对操作,因此可以用在with语句的头部。
如果你也有类似的计算过程需要抽取出来,那么可以自定义一个类,并且包含进入、退出方法。
总结
打开文件读写、用pickle包完成数据的存储、恢复的操作,都非常适合使用with语句。
pickle包的使用案例:
try: with open("phone.pickle", "wb") as outf: pickle.dump("13193388105", outf) except: print("file have errow.") try: with open("phone.pickle", "rb") as outf: data = pickle.load(outf) print(type(data)) print(data) except: print("file have errow.")
我总结了两个使用with语句的优点:
采用with语句的代码更简洁
防止因为忘记写f.close()而引发的错误
一个对象的操作有进入、退出过程可以抽取出来,并做成自动化执行
参考
《从问题到程序用Python编程和计算》
- python __enter__ 与 __exit__的作用,以及与 with 语句的关系
- python __enter__ 与 __exit__的作用,以及与 with 语句的关系
- Python with解析 __enter__()、__exit__() (十五)
- python with..as.. __call__ __enter__ __exit__
- python with语句执行过程
- python ------------- __enter__(),__exit__(),with
- 理解Python的With语句
- Python中的CSV文件使用"with"语句的方式详解
- python with魔法语句
- python中的with-as语句学习
- python基础----实现上下文管理协议__enter__和__exit__
- 浅谈 Python 的 with 语句
- Python入门--19--else语句、with语句
- 安装Python的psutil模块时报错:error: command 'gcc' failed with exit status 1
- python 中的反射,装饰器,with语句
- python中的__enter__ __exit__
- 浅谈 Python 的 with 语句
- 浅谈 Python 的 with 语句
- 理解Python的With语句
- [CentOS]安装MySQL-python,error: Setup script exited with error: command 'gcc' failed with exit status