python母亲节代码_python实践分享提高代码质量:使用with自动关闭资源

本文探讨了在Python中使用with自动关闭资源的常见误区,指出在看似简单的代码中,文件内容为空的原因。通过上下文管理器和with语句的工作原理,解释了为何即使记住关闭文件的重要性,也容易遗忘。同时揭示了with语句在资源管理和异常处理中的优势。
摘要由CSDN通过智能技术生成

34fae6cd7b899e510b41742b8a5c4735ca950dc7.jpeg?token=ba85a0a6794fa396d5ccd8fdd0d19236使用with自动关闭资源

来做个简单的试验,观察一下发生的现象。在Python解释器中输入下面两行代码,会有什么情况发生呢?

562c11dfa9ec8a13fcc412388b190e89a1ecc029.jpeg?token=65b05e78d72ebc82e2a20630c4f5057b使用with自动关闭资源

结果是:在解释器所在的目录下生成了一个文件test.txt,并且在里面写入了字符申test,对吗?

事实真相是:的确生成了一个文件,但其内容为空,并没有写入任何字符串。这个一个简单得不能再简单的问题,相信不用多说你已经知道症结所在了。

对文件操作完成后应该立即关闭它们,这是一个常识。我们都知道需要这么做,在很多编程语言中都会强调这个问题。因为打开的文件不仅会占用系统资源,而且可能影响其他 程序或者进程的操作,甚至会导致用户期望与实际操作结果不一致。

但实际应用中真相往往是:即使我们心中记得这个原则,但仍然可能会忘记关闭它。为什么?因为编程人员会把更多的精力和注意力放在对具体文件内容的操作和处理上;或者设计的正常流程是处理完毕关闭文件,但结果程序执行过程中发生了异常导致关闭文件的代码没有被执行到。也许你会说,还有try.finally块。对!

这是一种比较古老的方法,但Python提供了一种更为简单的解决方案:with语句。with语句的语法为:

with表达式[as目标]:

代码块

with语句支持嵌套,支持多个with子句,它们两者可以相互转换。"with exprl as el , expr2 as e2"与下面的嵌套形式等价:

4034970a304e251fe5e0fab5da9c56117f3e530c.jpeg?token=0528d1ff12f3a0f4af4ecd7f7ec10b59嵌套形式等价

with语句可以在代码块执行完毕后还原进入该代码块时的现场。包含有with语句的代码块的执行过程如下:

1)计算表达式的值,返回一个上下文管理器对象。

2)加载上下文管理器对象的_exit_()方法以备后用。

3)调用上下文管理器对象的_enter_()方法。

4)如果with语句中设置了目标对象,则将_enter_()方法的返回值赋值给目标对象。

5)执行with中的代码块。

6)如果步骤5中代码正常结束,调用上下文管理器对象的_exit_()方法,其返回值直接忽略。

7)如果步骤5中代码执行过程中发生异常,调用上下文管理器对象的_exit_()方法,并将异常类型、值及traccback信息作为参数传递给_exit_O方法。如果_exit_()返回值为 false,则异常会被重新抛出;如果其返回值为true,异常被挂起,程序继续执行。

在文件处理时使用with的好处在于无论程序以何种方式跳岀with块,总能保证文件被正确关闭。实际上它不仅仅针对文件处理.针对其他情景同样可以实现运行时环境的清理与还原,如多线程编程中的锁对象的管理。

with的神奇实际得益于一个称为上下文管理器 (context manager)的东西,它用来创建一个运行时的环境。上下文管理器是这样一个对象:它定义程序运行时需要建立的上下文,处理程序的进入和退出,实现了上下文管理协议,即在对象中定义_enter_()和_exit_()方法。其中:

1._enter_():进入运行时的上下文,返冋运行时上下文相关的对象,with语句中会将 这个返回值绑定到目标对象。如上面的例子中会将文件对象本身返回并绑定到目标f。

2.exit(exccption_type,exception_value,traceback):退出运行时的上下文,定义在块执行(或终止)之后上下文管理器应该做什么。它可以处理异常、清理现场或者处理with块中语句执行完成之后需要处理的动作。

实际上任何实现了上下文协议的对象都可以成为一个上下文管理器,文件也是实现了这个协议的上下文管理器,它们都能够与with语句兼容。文件对象的_enter_和_exit_属性如下:

dcc451da81cb39db9d59c6b2ac0c9622aa18305d.jpeg?token=e2e0a9c57712f4c54f187aeab2624fc0文件对象的_enter_和_exit_属性

用户也可以定义自己的上下文管理器来控制程序的运行,只需要实现上下文协议便能够和with语句一起使用。

a044ad345982b2b7c84330c34db754e977099bfd.jpeg?token=7b9d27027305dec8af8612a117b8bd50上下文管理器来控制程序

因为上下文管理器主要作用于资源共享,因此在实际应用中__enter__和__exit__ 法基本用于资源分配以及释放相关的工作,如打开/关闭文件、异常处理、断开流的连接、锁分配等。

为了更好地辅助上下文管理,Python还提供了contextlib模块,该模块是通过 Generator实现的,contextlib中的contextmanager作为装饰器来提供一种针对函数级别的上下文管理机制,可以直接作用于函数/对象而不用去关心_enter()_和_exit()_方法的具体实现。

马上母亲节了,记得给家里的妈妈一份问候

d6ca7bcb0a46f21fad7d7b06743ef4660c33ae3e.jpeg?token=5c87cbdda4636dbcf497413722fbef15母亲节

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值