Python上下文管理器实现方法总结
本文总结了Python中实现上下文管理器的三种主要方法。第一种是通过实现__enter__和__exit__协议手动构建类;第二种是利用contextlib.contextmanager装饰器简化生成器逻辑;第三种是使用contextlib.closing()强制调用close方法。文章通过具体代码示例对比了各方法的适用场景与实现细节,帮助开发者编写更优雅的Python代码。
何时适用上下文管理器
当代码逻辑涉及资源获取与释放、状态切换等需要确保清理操作被执行的情况时,使用上下文管理器能使代码结构更加清晰优雅。
try:
...
finally:
...
下文将详细介绍实现上下文管理器的三种常用方法。
方法一:基于上下文管理器协议
众所周知,内置函数open()默认支持上下文管理器。因此,打开一个txt文件并写入内容后自动关闭的代码可以简化为:
with open("1.txt", "w") as file:
file.write("this is a demo")
其等价于以下显式处理异常的写法:
file = None
try:
file = open("1.txt", "w")
file.write("this is a demo")
finally:
file.close()
要在Python中实现with语句的功能,必须借助上下文管理器协议,即实现__enter__和__exit__这两个特殊方法。
class OpenMyFile(object):
def __init__(self, path):
self.path = path
def __enter__(self):
print("opening the txt")
self.f = open(self.path, "w")
return self
def __exit__(self, *args, **kwargs):
print("closing the txt")
self.f.close()
def write(self, string):
print("writing...")
self.f.write(string)
with OpenMyFile("2.txt") as file:
file.write("this is a demo2")
# 输出:
opening the txt
writing...
closing the txt
执行上述代码后,本地会生成2.txt文件。需要注意的是,__enter__方法必须返回实例对象,否则会导致异常:AttributeError: 'NoneType' object has no attribute 'write'
这是因为Python函数默认返回None,若未显式返回实例,as绑定的变量将为None。
方法二:使用@contextmanager装饰器
利用contextlib模块中的contextmanager装饰器。
from contextlib import contextmanager
@contextmanager
def open_my_file(path):
print("opening the txt")
f = open("3.txt", "w")
yield f
print("closing the txt")
f.close()
with open_my_file("3.txt") as file:
file.write("this is demo3")
# 输出:
opening the txt
closing the txt
在@contextmanager装饰的函数中,需使用yield关键字分隔进入和退出逻辑。yield输出的对象将被as后的变量接收。
方法三:使用contextlib.closing()
利用contextlib模块中的closing()函数。
from contextlib import closing
class OpenMyFile(object):
def __init__(self, path):
print("opening the txt")
self.f = open(path, "w")
def write(self, string):
self.f.write(string)
def close(self):
print("closing the txt")
self.f.close()
with closing(OpenMyFile("4.txt")) as file:
file.write("this is demo4")
# 输出:
opening the txt
closing the txt
与方法一不同,经过closing()包装后,在with语句结束时会自动强制调用对象的close()方法。因此,使用方法三时,需要定义的方法是close()而非__exit__()。
至此,关于Python上下文管理器三种实现方法的介绍完毕。如需了解更多相关内容,可搜索本站往期文章或继续浏览后续文章,感谢大家的支持!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









