with 语句是 Pyhton 提供的一种简化语法,适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的“清理”操作,释放资源,with 语句主要是为了简化代码操作。
with:文件使用后自动关闭
# 创建一个文件test.txt,若存在则打开,写入Hello Python
# 创建/打开文件
f = open('test.txt', 'w')
f.write("Hello Python")
# 关闭这个文件
f.close()
# 使用with
with open('test.txt', 'w') as f:
f.write('Python')
可以发现:通过 with 语句在编写代码时,会使代码变得更加简洁,不用再去关闭文件。
with的执行过程:
1.在执行 with 语句时,首先执行 with 后面的 open 代码
2.执行完代码后,会将代码的结果通过 as 保存到 f 中
3.然后在下面实现真正要执行的操作
4.在操作后面,并不需要写文件的关闭操作,文件会在使用完后自动关闭
with的执行原理
实际上,在文件操作时,并不是不需要写文件的关闭,而是文件的关闭操作在 with 的上下文管理器中的协议方法里已经写好了。当文件操作执行完成后, with语句会自动调用上下文管理器里的关闭语句来关闭文件资源。
上下文管理器
ContextManager ,上下文是 context 直译的叫法,在程序中用来表示代码执行过程中所处的前后环境。上下文管理器中有 __enter__
和 __exit__
两个方法,以with为例子,
1.__enter__
方法会在执行 with 后面的语句时执行,一般用来处理操作前的内容。比如一些创建对象,初始化等;
2.__exit__
方法会在 with 内的代码执行完毕后执行,一般用来处理一些善后收尾工作,比如文件的关闭,数据库的关闭等。
今天我们可以把open重新实现以下也看一下文件读取的内部原理:
class Myopen():
def __init__(self,file_name,method,encoding):
self.file_name=file_name
self.method=method
self.encoding=encoding
self.f=open(self.file_name,self.method,encoding=self.encoding)
def __enter__(self):
print('-----exit-----')
#打开文件操作
#返回打开的文件对象引用, 用来给 as 后的变量f赋值
return self.f
def __exit__(self, exc_type, exc_val, exc_tb):
print('-----exit------')
#执行关闭文件操作
self.f.close()
#Myopen()创建对象,需要初始化则需要init
with Myopen('0830.md','r',encoding='utf8') as f: 方法
print(f.read()) #由enter中返回值决定
print('-----with的代码-----')