原文地址:Python中的With…as语句(简书-惑也)
一、语法
with context as var: with_suite
with语句:可以代替try…except…finally语句,使代码更加简洁;context:通常是表达式,返回一个对象;var变量:用来保存context返回的对象,可以是单个值或元组;with_suite:使用变量var对context返回对象进行各种操作的代码段
二、示例
# 查看文件内容XZ:learn xz$ cat with.txt with...as...12345abcdeIn [2]: with open('with.txt','r+') as f: ...: for line in f.readlines(): ...: print(line) ...: print('with is closed : ', f.closed) ...: ...: with...as...12345abcdewith is closed : True
- 打开文本
with.txt,f变量接收文件对象返回的对象; - 读取文本中的内容,逐行打印;
with中的代码执行完成后,会自动关闭文件;- 如果
with语句中没有做try...except异常处理,出现错误时会直接将异常交给Python解释器抛出,不会自动关闭文件,如果做了try...except异常处理,出现异常时,会自动关闭文件,再抛出异常。
三、原理
- with语句实质上是上下文管理
- 上下文管理协议:包含2个方法:
__enter__和__exit__; - 支持该协议的对象,要实现这2个方法,才能被with语句进行操作。
- 上下文管理器
- 定义执行with语句时建立的运行时上下文,负责执行with语句上下文的进入和退出操作;
- 进入上下文管理器:调用管理器
__enter__方法,如果设置了as var语句,变量var接受__enter__方法的返回值; - 退出上下文管理器:调用管理器的
__exit__方法。
四、应用场景
- 文件操作
- 进程线程之间互斥对象,如互斥锁
- 自定义的支持上下文的其它操作
五、我的实践
"""with语句处理异常 我们知道使用try-except-finally语句可以处理异常,接下来我们介绍使用with语句处理与异常相关的工作 with语句支持创建资源,抛出异常,释放资源等操作,并且代码简洁。with语句格式 with 上下文表达式 [as 资源对象]: 对象操作 说明: 上下文表达式,返回一个上下文管理对象 如果指定了as语句,该对象并不赋值给as子句中的资源对象,而是将上下文管理器的__enter__()方法的返回值赋值给了资源对象。 资源对象可以是单变量,也可以是元组。使用with语句操作文件对象"""with open("test.txt") as file: for aline in file: print(aline)"""解释说明: 这段代码使用with语句打开文件,如果顺利打开,则将文件对象赋值给file,然后用for语句遍历打印文件的每一行。当文件操作结束后,with语句关闭文件。如果这段代码运行过程中发生异常,with也会将文件关闭。这段代码使用finally语句实现如下:"""try: file = open("test.txt") try: for aline in file: print(aline) except Exception as error: print(error) finally: file.close()except FileNotFoundError as err: print(err)"""我们也可以给with语句加上异常处理:"""try: with open("test.txt") as file: for aline in file: print(aline)except Exception as error: print(error)"""通过对比可以发现:with语句在进行异常处理时代码简洁很多特别说明: 不是所有的对象都可以使用with语句,只有支持上下文管理协议的对象才可以。目前支持上下文管理协议的对象如下:"""# file# decimal.Context# thread.LockType# threading.BoundedSemaphore# threading.Condition# threading.Lock# threading.RLock# threading.Semaphore