Python 上下文管理

上下文管理

python的上下文管理可以方便用于管理资源的分配与回收。一般通过with进行使用,比如经常可见的文件操作:

with open("path_to_file", "r") as f:
	f.read()

在这样的上下文管理下,用户可以打开文件后,可以不用关心的文件的释放,甚至在文件打开成功打开,但是执行出错时,也会正确释放文件资源。事实上这样的代码对应的等价代码为:

f = open("path_to_file", "r")
try:
	f.read()
finally:
	f.close()

对于就可以知道,采用上下文管理的方式,可以大大缩短代码

类实现上下文管理

对于上下文管理,无非是在执行真正的操作前执行预处理,在执行解释后进行清理工作,而且清理工作是必须执行的,即使出现了异常,清理也会执行。在python中,可以利用魔术方法__enter____exit__进行实现,当使用with进行配合时,__enter__会在真正操作前执行,而__exit__会在操作后执行。实例代码如下:

class context_manager(object):

    def __enter__(self):
        print 'Do prepare'
    
    def __exit__(self, *args):
        print 'Do clean up'

with context_manager():
	print 'Do my work'

执行上面的代码可以看到,会先打印出’Do prepare’,然后打印出’Do my work’,最后打印出’Do clean up’,可以看到利用__enter____exit__可以轻松实现上下文的管理。在实际中,可以将资源的申请操作写在__enter__方法中,将资源的释放写在__exit__中。

基于生成器实现上下文管理

为了实现上下文管理,还可以使用生成器(如果不理解生成器可以参考之前的博客)进行实现

from contextlib import contextmanager

@contextmanager
def context_manager():
    print 'Do prepare'
    yield
    print 'Do clean up'
    
with context_manager():
	print 'Do my work'

可以看到,最初属于与前面相同,比较简单实现了上下文管理器。在yield前执行预处理,在yield后执行清理工作,不需要构建类也实现了上下文管理。但是真的完全等价吗,其实是有不同的,可以将两种实现的print 'Do my work'都修改为 raise Exception(),就会发现区别,采用类实现的上下文管理,在出现异常的情况下可以执行清理工作,基于生成器的方式却会直接退出,不会执行清理工作。那么如何修改可以让这种实现方式处理异常情况呢。可以参考如下代码:

from contextlib import contextmanager

@contextmanager
def context_manager():
    print 'Do prepare'
    try:
    	yield
    finally:
    	print 'Do clean up'
    
with context_manager():
	print 'Do my work'

按照这样方式,捕获所有异常,但是利用finally保证必然会执行清理代码,这样就能达到和前面的类实现的上下文管理器一样完整的上下文管理器功能了。

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Python 上下文管理器(Context Manager)是一种用于管理资源的特殊对象,它定义了在进入和离开代码块时应该执行的操作。上下文管理器通常与 `with` 语句一起使用,用于确保资源在使用完毕后被正确释放。 在 Python 中,上下文管理器可以通过实现 `__enter__` 和 `__exit__` 方法来创建。`__enter__` 方法定义了进入代码块时要执行的操作,而 `__exit__` 方法定义了离开代码块时要执行的操作。当代码块执行完毕或发生异常时,`__exit__` 方法会自动被调用。 下面是一个简单的示例,演示了如何使用上下文管理器来打开和关闭文件: ```python class FileManager: def __init__(self, filename): self.filename = filename def __enter__(self): self.file = open(self.filename, 'r') return self.file def __exit__(self, exc_type, exc_val, exc_tb): self.file.close() # 使用上下文管理器打开文件 with FileManager('example.txt') as file: data = file.read() # 在此处进行文件操作 # 文件已经自动关闭,不需要手动调用 file.close() ``` 在上述示例中,`FileManager` 类实现了 `__enter__` 和 `__exit__` 方法。在 `__enter__` 方法中,我们打开了文件并将其返回,使得在 `with` 语句块中可以使用该文件对象。当代码块执行完毕或发生异常时,`__exit__` 方法会被调用,确保文件被关闭。 上下文管理器的一个重要用途是确保资源的正确释放,比如关闭文件、释放锁等。它使得代码更加简洁、可读性更高,并且可以避免常见的资源泄漏问题。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

易迟

高质量内容创作不易,支持下

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值