Python:上下文管理器with-简直不要太好用。

Python 中的 with 语句用于异常处理,封装了 try…except…finally 编码范式,提高了易用性。with 语句使代码更清晰、更具可读性, 它简化了文件流等公共资源的管理。在处理文件对象时使用 with 关键字是一种很好的做法。

一、Python 中的with使用

  在python中涉及资源管理的处理时候,我们通常会使用下面这种方式实现;

with open(filepath, 'r') as f:
# your code

  因为通常这类操作会涉及到资源的占用以及控制器的锁定,所以我们有必要对异常情况进行处理。当然,你也可以用

try:
	pass # 需要错误处理的代码
except:
	pass # 当上述代码发生错误时候进行的操作
finally:
	pass # 无论前面两者的执行状态如何都进行的操作

  当对两种写法进行比较时候我们发现,with的写法更加简洁且需要关心的操作更加集中;通过对源码的分析,发现with处理的对象实现了上下文管理协议(context manage)

上下文管理协议,即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明__enter__和__exit__方法。

  with是一种控制流协议,其执行过程是:
  1、调用context_expression,获取上下文管理对象;
  2、调用上述对象的__enter__()方法,执行初始化操作,并返回一个值。若通过as子语句进行别名,则将返回值赋值给target(s);其中,初始化操作由实现__enter__()方法的对象自主实现, with仅关注最后的返回值;
  3、初始化完成后,执行with包含body中的代码块。
  4、在执行代码块完成或对象被销毁时,上下文管理器中的__exit__()会被调用。
  当代码块无异常时,exit()函数会执行一些释放资源的操作,例如关闭文件、断开链接等操作。

  当代码块中发生异常时,涉及到__exit__()函数中的这几个参数:exc_type, exc_val, exc_tb。可见官方文档:

官方文档链接:
https://docs.python.org/3/reference/datamodel.html#object

官方文档链接: https://docs.python.org/3/reference/datamodel.html#object.__exit__

二、With的其他用法。

  1. with 嵌套:可以将多个 with 语句嵌套,即一个 with 语句块中还包含另一个 with 语句块,用法如下:
with open('file1.txt', 'r') as f1:
    with open('file2.txt', 'w') as f2:
        # do something
  1. 自定义 with 语句块:可以通过定义一个类实现自己的 with 语句,实现方法是定义一个类并实现 enter() 和 exit() 方法,enter() 方法在 with 语句块开始时被调用,exit() 方法在 with 语句块结束时被调用。用法如下:
class MyContextManager:
    def __init__(self, name):
        self.name = name
    def __enter__(self):
        print(f'Entering {self.name}')
        return self
    def __exit__(self, exc_type, exc_value, traceback):
        print(f'Exiting {self.name}')
    
with MyContextManager('context') as cm:
    # do something
  1. with 语句使用多个上下文管理器:在 with 语句中使用多个上下文管理器,这样就可以同时管理多个资源。用法如下:
with open('file1.txt', 'r') as f1, open('file2.txt', 'w') as f2:
    # do something

三、关于错误处理

如果with语句内部发生的错误没有被处理或捕获,那么会向上层抛出异常,并被外部的try语句捕获。因此,如果with语句内部出现了问题,并且没有被处理,那么外部的try语句是可以捕获到这个错误的。如果with语句内部的错误被处理或捕获了,那么外部的try语句是无法捕获到这个错误的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值