位置: 编程技术 - 正文

Python标准模块--ContextManager上下文管理器的具体用法(python标准模板库)

编辑:rootadmin

推荐整理分享Python标准模块--ContextManager上下文管理器的具体用法(python标准模板库),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:python标准模板库,python标准模块calendar,python c模块,python内置的标准模块,python内置的标准模块,python标准模块calendar,Python标准模块为什么叫自带电池?,python标准模块calendar,内容如对您有帮助,希望把文章链接给更多的朋友!

写代码时,我们希望把一些操作放到一个代码块中,这样在代码块中执行时就可以保持在某种运行状态,而当离开该代码块时就执行另一个操作,结束当前状态;所以,简单来说,上下文管理器的目的就是规定对象的使用范围,如果超出范围就采取“处理”。

这一功能是在Python2.5之后引进的,它的优势在于可以使得你的代码更具可读性,且不容易出错。

1 模块简介

在数年前,Python 2.5 加入了一个非常特殊的关键字,就是with。with语句允许开发者创建上下文管理器。什么是上下文管理器?上下文管理器就是允许你可以自动地开始和结束一些事情。例如,你可能想要打开一个文件,然后写入一些内容,最后再关闭文件。这或许就是上下文管理器中一个最经典的示例。事实上,当你利用with语句打开一个文件时,Python替你自动创建了一个上下文管理器。

如果你使用的是Python 2.4,你不得不以一种老的方式来完成这个任务。

上下文管理器背后工作的机制是使用Python的方法:__enter__和__exit__。让我们尝试着去创建我们的上下文管理器,以此来了解上下文管理器是如何工作的。

2 模块使用

2.1 创建一个上下文管理器类

与其继续使用Python打开文件这个例子,不如我们创建一个上下文管理器,这个上下文管理器将会创建一个SQLite数据库连接,当任务处理完毕,将会将其关闭。下面就是一个简单的示例。

在上述代码中,我们创建了一个类,获取到SQLite数据库文件的路径。__enter__方法将会自动执行,并返回数据库连接对象。现在我们已经获取到数据库连接对象,然后我们创建光标,向数据库写入数据或者对数据库进行查询。当我们退出with语句的时候,它将会调用__exit__方法用于执行和关闭这个连接。

让我们使用其它的方法来创建上下文管理器。

2.2 利用contextlib创建一个上下文管理器

Python 2.5 不仅仅添加了with语句,它也添加了contextlib模块。这就允许我们使用contextlib的contextmanager函数作为装饰器,来创建一个上下文管理器。让我们尝试着用它来创建一个上下文管理器,用于打开和关闭文件。

在这里,我们从contextlib模块中引入contextmanager,然后装饰我们所定义的file_open函数。这就允许我们使用Python的with语句来调用file_open函数。在函数中,我们打开文件,然后通过yield,将其传递出去,最终主调函数可以使用它。

一旦with语句结束,控制就会返回给file_open函数,它继续执行yield语句后面的代码。这个最终会执行finally语句--关闭文件。如果我们在打开文件时遇到了OSError错误,它就会被捕获,最终finally语句依然会关闭文件句柄。

contextlib.closing(thing)

contextlib模块提供了一些很方便的工具。第一个工具就是closing类,一旦代码块运行完毕,它就会将事件关闭。Python官方文档给出了类似于以下的一个示例,

Python标准模块--ContextManager上下文管理器的具体用法(python标准模板库)

在这段代码中,我们创建了一个关闭函数,它被包裹在contextmanager中。这个与closing类相同。区别就是,我们可以在with语句中使用closing类本身,而非装饰器。让我们看如下的示例,

在这个示例中,我们在closing类中打开一个url网页。一旦我们运行完毕with语句,指向网页的句柄就会关闭。

contextlib.suppress(*exceptions)

另一个工具就是在Python 3.4中加入的suppress类。这个上下文管理工具背后的理念就是它可以禁止任意数目的异常。假如我们想忽略FileNotFoundError异常。如果你书写了如下的上下文管理器,那么它不会正常运行。

正如你所看到的,这个上下文管理器没有处理这个异常,如果你想忽略这个错误,你可以按照如下方式来做,

在这段代码中,我们引入suppress,然后将我们要忽略的异常传递给它,在这个例子中,就是FileNotFoundError。如果你想运行这段代码,你将会注意到,文件不存在时,什么事情都没有发生,也没有错误被抛出。请注意,这个上下文管理器是可重用的,2.4章节将会具体解释。

contextlib.redirect_stdout/redirect_stderr

contextlib模块还有一对用于重定向标准输出和标准错误输出的工具,分别在Python 3.4 和3.5 中加入。在这些工具被加入之前,如果你想对标准输出重定向,你需要按照如下方式操作,

利用contextlib模块,你可以按照如下方式操作,

在上面两个例子中,我们均是将标准输出重定向到一个文件。当我们调用Python的help函数,不是将信息输出到标准输出上,而是将信息保存到重定向的文件中。你也可以将标准输出重定向到缓存或者从用接口如Tkinter或wxPython中获取的文件控制类型上。

2.3 ExitStack

ExitStack是一个上下文管理器,允许你很容易地与其它上下文管理结合或者清除。这个咋听起来让人有些迷糊,我们来看一个Python官方文档的例子,或许会让我们更容易理解它。

这段代码就是在列表中创建一系列的上下文管理器。ExitStack维护一个寄存器的栈。当我们退出with语句时,文件就会关闭,栈就会按照相反的顺序调用这些上下文管理器。

Python官方文档中关于contextlib有很多示例,你可以学习到如下的技术点:

从__enter__方法中捕获异常 支持不定数目的上下文管理器 替换掉try-finally 其它

2.4 可重用的上下文管理器

大部分你所创建的上下文管理器仅仅只能在with语句中使用一次,示例如下:

在这段代码中,我们创建了一个上下文管理器实例,并尝试着在Python的with语句中运行两次。当第二次运行时,它抛出了RuntimeError。

但是如果我们想运行上下文管理器两次呢?我们需要使用可重用的上下文管理器。让我们使用之前所用过的redirect_stdout这个上下文管理器作为示例,

在这段代码中,我们创建了一个上下文管理器,它们均向StringIO(一种内存中的文件流)写入数据。这段代码正常运行,而没有像之前那样抛出RuntimeError错误,原因就是redirect_stdout是可重用的,允许我们可以调用两次。当然,实际的例子将会有更多的函数调用,会更加的复杂。一定要注意,可重用的上下文管理器不一定是线程安全的。如果你需要在线程中使用它,请先仔细阅读Python的文档。

2.5 总结

上下文管理器很有趣,也很方便。我经常在自动测试中使用它们,例如,打开和关闭对话。现在,你应该可以使用Python内置的工具去创建你的上下文管理器。你还可以继续阅读Python关于contextlib的文档,那里有很多本文没有覆盖到的知识。

标签: python标准模板库

本文链接地址:https://www.jiuchutong.com/biancheng/375451.html 转载请保留说明!

上一篇:利用信号如何监控Django模型对象字段值的变化详解(信号监控设备是什么)

下一篇:Python基于贪心算法解决背包问题示例(基于贪心算法)

  • 增值税普票没有税号可以开吗
  • 小规模纳税人免税会计分录
  • 固定资产怎么确定是否减值
  • 一般纳税人销售使用过的固定资产
  • 出口退税是按照出口金额吗
  • 企业注销盈利一定要交个税吗
  • 普通发票需要进项税额转出吗
  • 退税抵税申请表
  • 合并抵消分录的原理是什么
  • 结转损益类账户余额
  • 托收承付和委托收款的含义和相同之处
  • 罚款所得税调整
  • 项目部租房办公应计入什么费用
  • 收银系统已入库怎么操作
  • 借款可以转注资款吗
  • 个人抬头发票能开专票吗
  • 电子承兑必须对账吗
  • 增资的印花税纳税义务时间
  • 税控盘维护费280怎么交
  • 水利建设基金的计税依据及税率
  • 业务招待费怎么调整应纳税所得额
  • 汽车罚款怎么进账
  • 网上申报城建税及附加怎么操作
  • 关于解决经费问题的请示
  • 进口货物如何缴增值税
  • i911900k与10900k
  • ati2mdxx.exe是什么进程 ati2mdxx进程信息查询
  • 代办退税账务处理
  • 商业企业低值易耗品科目核算的内容
  • 成本法转为权益法追溯的理解
  • 竣工结算的依据有哪些?
  • php清除缓存的几个方法
  • vue项目打包后还能修改吗
  • PHP使用http_build_query()构造URL字符串的方法
  • TypeError The view function did not return a valid response. The function either returned None 的解决
  • 运输中合理损耗计入采购成本
  • easyposer怎么导出
  • opencv教程
  • php魔术方法autoload
  • 2022年最新公务员职务职级对照表
  • 如何计提所得税费用科目
  • 提取法定盈余公积的公式
  • 工资和五险一金在公司发,个税在子公司扣
  • tomcat结构图
  • mongodb win7
  • 织梦使用教程
  • 如何修改mysql
  • 普通发票能不能重新开
  • 车辆购置税可以网上缴纳吗
  • 会计电算化的内容和任务
  • 哪些情况需要开具无违法犯罪证明
  • 工会经费会计分录最新
  • 生产成品出库的会计分录
  • 营改增后税率
  • 增值税发票税率计算公式
  • 试算不平衡的原因是什么
  • 长期股权投资如何入账
  • 减免增值税如何申报
  • 发票金额大于付款金额可以报销吗
  • 财务人员需要填报的报表有哪些
  • 总帐设置在哪
  • sql将查询的结果拼接
  • 文件历史版本功能
  • ubuntu安装哪个版本
  • windows不认u盘
  • win7系统磁盘分区必须分区为什么才能安装
  • win7系统如何调节电脑屏幕亮度
  • winxp的控制面板在哪里
  • 列举linux常用的几个命令
  • node async await
  • python 管理内存
  • 使用forever管理nodejs应用教程
  • WWW封装共享 [复制链接]
  • linux的gunzip命令
  • js间隔执行的代码
  • 上海烟草集团董事长是谁
  • 广东省电子税务局电话
  • 核准类结算账户包括
  • 北京地税电话咨询
  • 全国初中应用物理知识竞赛获奖名单
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设