with
不安全代码(这个关闭有可能关闭不上)
f = open("a.txt",encoding="utf-8")
print(f.read)
print(1 / 0)
f.close()#关闭流!
解决办法:
f = open("a.txt",encoding="utf-8")
try:
print(f.read())
print(1 / 0)
except:
pass
finally:
f.close()
如上,逻辑正确代码冗余
使用 with 打开文件:
with open("a.txt",encoding="utf-8") as f:
print(f.read())
print(1 / 0)
注意:因实际开发过程中,打开文件很容易忘记关闭文件,造成内存不能释放,所以一般可以
选择使用 with open 方法打开文件
with 资源释放
with 语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的“清理”操作,释放资源,比如文件使用后自动关闭/线程中锁的自动获取和释放等
with 工作原理
(1)紧跟 with 后面的语句被求值后,返回对象的“–enter–()”方法被调用,这个方法的返回值将被赋值给 as 后面的变量;
(2)当 with 后面的代码块全部被执行完之后,将调用前面返回对象的“–exit–()”方法。
with 工作原理代码示例:
class demo():
def __enter__(self):#定义这个方法
print("进入enter方法")
return "你好"#一定会经过这一步
def __exit__(self, exc_type, exc_val, exc_tb):#检测是否有异常,所有都执行完进入exit
#【注:】exit()方法中有3个参数, exc_type, exc_val, exc_tb,这些参数在常处理中相当有用。exc_type: 错误的类型exc_val: 错误类型对应的值exc_tb: 代码中错误发生的
print("进入enter方法")
print("---",exc_type)
print("---",exc_val)
print("---",exc_tb)
def test():
return demo()#返回demo对象 自动调用__enter__
with test() as t:#将__enter__返回值赋给t
print(t)
print(1/0)#打印异常
总结
实际上,在 with 后面的代码块抛出异常时,exit()方法被执行。开发库时,清理资源,关闭文件等操作,都可以放在 exit()方法中。总之,with-as 表达式极大的简化了每次写 finally 的工作,这对代码的优雅性是有极大帮助的。
如果有多项,可以这样写:
With open('1.txt') as f1, open('2.txt') as f2:
do something