编程中有不少操做都是配套使用的,这种配套的流程能够称为计算过程,Python语言为这种计算过程专门设计了一种结构:with语句。好比文件处理就是这类计算过程的典型表明。python
没有使用with语句以前,咱们是这样打开一个文件的:编程
try: # 1. [进入] f = open('a.txt', 'r', encoding="utf-8") # 2. [执行] print(f.read()) finally: if f: # 3. [退出] f.close()
python操做文件的流程通常就是这三步:函数
思考为何关闭文件操做必定要放在finallly语句里?
因为文件读写时都有可能产生IOError,一旦出错,后面的f.close()就不会调用。因此,为了保证不管是否出错都能正确地关闭文件,咱们可使用try ... finally来实现。操作系统
发现共性:
咱们发现其实这种过程化的语句有共性,好比说在进去一个片断前
必须作某种超赞,处理工做后
又须要执行一个结束操做。好比上面的这段代码:设计
finally: if f: f.close()
就能够作一个封装。code
使用with语句后,咱们是这样打开一个文件的:对象
with open("a.txt", "r", encoding="utf-8") as f: print(f.read())
这个with语句和前面的try ... finally结构是同样的,可是代码更佳简洁,而且没必要调用f.close()方法。内存
从解释器的角度去理解with语句执行流程。utf-8
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编程和计算》