python的上下文环境管理
try/except模块的finally
finally绝对最后执行
def func():
try :
print('trying')
raise KeyError
return 0
except KeyError as e:
print('catch Keyerror')
return 'keyerror'
finally:
print('finally')
return '114514'
print('func return : '+ func())
运行上述代码,except和finally模块都会执行,但最后的返回值?
返回了finally的返回值,可见函数在except中仍然不会遇见return语句后立刻结束,依然会执行到finally中。由此,如果涉及文件的关闭时,可以将关闭语句写在finally中,保证文件关闭,回收资源。
def func():
try :
print('trying')
f = open('./test.xlsx')
except KeyError as e:
print('catch Keyerror')
return 'keyerror'
finally:
print('finally')
f.close()
return '114514'
print('func return : '+ func())
with管理
常见的with管理代码:
with open('./.txt', 'w') as file:
file.write('hello world !')
文件的打开关闭将交由with进行管理,无需手动管理。
with 语句也是上下文管理协议的一部分,协议是一个类需要实现 enter 和 exit 方法。
class Sample:
def __enter__(self):
print('getting resources')
return self
def __exit__(self, exc_type, exc_value, traceback):
print('exiting resources')
def work(self):
print('file working')
with Sample() as s:
s.work()
只要类实现了__enter__和__exit__方法,就能在with实例化后接受上下文的自动管理。
contextlib的contextmanager类管理
import contextlib
@contextlib.contextmanager
def file_open(file_name):
print('file open')
file = open(file_name,'r')
yield file
print('file end')
file.close()
with file_open('example.txt') as f:
contents = f.read()
print(contents)
这里的注意使用的是yield返回文件而不是return。因为在上下文管理器中,我们使用yield语句使函数成为一个生成器(generator)函数。生成器函数可以在执行过程中暂停并保存状态,然后在下一次调用时从暂停的地方继续执行。
在上下文管理器中,yield语句之前的代码块会在进入上下文时执行(类似于__enter__()方法),而yield语句之后的代码块会在离开上下文时执行(类似于__exit__()方法)。yield语句之前的代码块用于生成上下文管理器的值,可以在with语句中使用。在示例中,使用yield file将打开的文件对象作为上下文管理器的值返回。
当使用with语句创建上下文管理器时,yield语句之前的代码被执行,并将生成的值绑定到as子句中的变量上(在示例中是f)。在with块中,我们可以使用这个变量来操作上下文管理器的值(在示例中是文件对象)。
yield语句之后的代码块会在离开with块时执行,用于处理清理操作,比如关闭文件。无论是通过正常执行还是发生异常,这部分代码都会被执行,来确保资源的正确释放。