全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

Python上下文管理器和with块详解

上下文管理器和with块,具体内容如下

上下文管理器对象存在的目的是管理 with 语句,就像迭代器的存在是为了管理 for 语句一样。

with 语句的目的是简化 try/finally 模式。这种模式用于保证一段代码运行完毕后执行某项操作,即便那段代码由于异常、 return 语句或 sys.exit() 调用而中止,也会执行指定的操作。 finally 子句中的代码通常用于释放重要的资源,或者还原临时变更的状态。

==上下文管理器协议包含enter和exit两个方法==。 with 语句开始运行时,会在上下文管理器对象上调用enter方法。 with 语句运行结束后,会在上下文管理器对象上调用exit方法,以此扮演 finally 子句的角色。

==执行 with 后面的表达式得到的结果是上下文管理器对象,把值绑定到目标变量上(as 子句)是在上下文管理器对象上调用enter方法的结果==。with 语句的 as 子句是可选的。对 open 函数来说,必须加上 as子句,以便获取文件的引用。不过,有些上下文管理器会返回 None,因为没什么有用的对象能提供给用户。

with open('mirror.py') as fp:
  ...

自定义的上下文类:

class A:
  def __init__(self, name):
    self.name = name

  def __enter__(self):
    print('enter')
    return self.name

  def __exit__(self, exc_type, exc_val, exc_tb):
    print('gone')

with A('xiaozhe') as dt:
  print(dt)

contextlib模块

contextlib 模块中还有一些类和其他函数,使用范围更广。

closing:如果对象提供了 close() 方法,但没有实现enter/exit协议,那么可以使用这个函数构建上下文管理器。
suppress:构建临时忽略指定异常的上下文管理器。
@contextmanager:==这个装饰器把简单的生成器函数变成上下文管理器==,这样就不用创建类去实现管理器协议了。
ContextDecorator:这是个基类,用于定义基于类的上下文管理器。这种上下文管理器也能用于装饰函数,在受管理的上下文中运行整个函数
ExitStack:这个上下文管理器能进入多个上下文管理器。 with 块结束时, ExitStack 按照后进先出的顺序调用栈中各个上下文管理器的exit方法。

==使用最广泛的是 @contextmanager 装饰器,因此要格外留心。这个装饰器也有迷惑人的一面,因为它与迭代无关,却要使用 yield 语句==。

使用@contextmanager

@contextmanager 装饰器能减少创建上下文管理器的样板代码量,不用编写一个完整的类定义enter和exit方法,而只需实现有一个 yield 语句的生成器,生成想让enter方法返回的值。

在使用 @contextmanager 装饰的生成器中, yield 语句的作用是把函数的定义体分成两部分: ==yield 语句前面的所有代码在 with 块开始时(即解释器调用enter方法时)执行, yield 语句后面的代码在 with 块结束时(即调用exit方法时)执行==。

import contextlib

@contextlib.contextmanager
def test(name):
  print('start')
  yield name
  print('end')

with test('zhexiao123') as dt:
  print(dt)
  print('doing something')

实现原理

contextlib.contextmanager 装饰器会把函数包装成实现enter和exit方法的类。类的名称是 _GeneratorContextManager。

这个类的enter方法有如下作用:
1. 调用生成器函数,保存生成器对象(这里把它称为 gen)。
2. 调用 next(gen),执行到 yield 关键字所在的位置。
3. 返回 next(gen) 产出的值,以便把产出的值绑定到 with/as 语句中的目标变量上。

with 块终止时,exit方法会做以下几件事:

1. 检查有没有把异常传给 exc_type;如果有,调用 gen.throw(exception),在生成器函数定义体中包含 yield 关键字的那一行抛出异常。
2. 否则,调用 next(gen),继续执行生成器函数定义体中 yield 语句之后的代码。

异常处理

为了告诉解释器异常已经处理了,exit方法会返回 True,此时解释器会压制异常。如果exit方法没有显式返回一个值,那么解释器得到的是 None,然后向上冒泡异常。

使用 @contextmanager 装饰器时,默认的行为是相反的:装饰器提供的exit方法假定发给生成器的所有异常都得到处理了,因此应该压制异常。 如果不想让 @contextmanager 压制异常,必须在被装饰的函数中显式重新抛出异常。

上面的代码有个bug:如果在 with 块中抛出了异常, Python 解释器会将其捕获,然后在 test 函数的 yield 表达式里再次抛出。但是,那里没有处理错误的代码,因此 test 函数会中止。

使用 @contextmanager 装饰器时,要把 yield 语句放在 try/finally 语句中,因为我们永远不知道上下文管理器的用户会在 with 块中做什么。

import contextlib

@contextlib.contextmanager
def test(name):
  print('start')

  try:
    yield name
  except:
    raise ValueError('error')
  finally:
    print('end')

with test('zhexiao123') as dt:
  print(dt)
  print('doing something')

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


# Python  # 上下文管理器  # with块  # 详解Python中的with语句和上下文管理器  # python中with语句结合上下文管理器操作详解  # Python中的上下文管理器和with语句的使用  # Python with语句上下文管理器两种实现方法分析  # Python中的with语句与上下文管理器学习总结  # 详解python with 上下文管理器  # Python基础之with语句和上下文管理器详解  # 管理器  # 子句  # 抛出  # 会在  # 的是  # 想让  # 绑定  # 结束时  # 迭代  # 是在  # 也有  # 放在  # 也会  # 有个  # 就像  # 多个  # 目的是  # 也能  # 只需  # 把它 


相关文章: 怎么制作一个起泡网,水泡粪全漏粪育肥舍冬季氨气超过25ppm,可以有哪些措施降低舍内氨气水平?  企业在线网站设计制作流程,想建设一个属于自己的企业网站,该如何去做?  如何在阿里云虚拟机上搭建网站?步骤解析与避坑指南  建站之星后台管理:高效配置与模板优化提升用户体验  建站之星代理如何获取技术支持?  如何快速生成橙子建站落地页链接?  相亲简历制作网站推荐大全,新相亲大会主持人小萍萍资料?  ,交易猫的商品怎么发布到网站上去?  如何快速完成中国万网建站详细流程?  如何基于云服务器快速搭建个人网站?  如何用狗爹虚拟主机快速搭建网站?  如何在阿里云通过域名搭建网站?  建站之星2.7模板快速切换与批量管理功能操作指南  营销式网站制作方案,销售哪个网站招聘效果最好?  如何快速搭建安全的FTP站点?  网站制作公司广州有几家,广州尚艺美发学校网站是多少?  如何快速建站并高效导出源代码?  网站制作新手教程,新手建设一个网站需要注意些什么?  如何通过可视化优化提升建站效果?  建站之星图片链接生成指南:自助建站与智能设计教程  建站之星如何快速解决建站难题?  建站之星在线客服如何快速接入解答?  如何选择高效可靠的多用户建站源码资源?  大连网站制作公司哪家好一点,大连买房网站哪个好?  如何通过NAT技术实现内网高效建站?  建站之星ASP如何实现CMS高效搭建与安全管理?  ,sp开头的版面叫什么?  头像制作网站在线制作软件,dw网页背景图像怎么设置?  定制建站如何定义?其核心优势是什么?  jQuery 常见小例汇总  c++怎么使用类型萃取type_traits_c++ 模板元编程类型判断【方法】  广东专业制作网站有哪些,广东省能源集团有限公司官网?  如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱?  成都网站制作报价公司,成都工业用气开户费用?  如何处理“XML格式不正确”错误 常见XML well-formed问题解决方法  如何彻底删除建站之星生成的Banner?  如何在万网自助建站中设置域名及备案?  合肥制作网站的公司有哪些,合肥聚美网络科技有限公司介绍?  官网自助建站系统:SEO优化+多语言支持,快速搭建专业网站  全景视频制作网站有哪些,全景图怎么做成网页?  广东企业建站网站优化与SEO营销核心策略指南  官网建站费用明细查询_企业建站套餐价格及收费标准指南  详解一款开源免费的.NET文档操作组件DocX(.NET组件介绍之一)  招商网站制作流程,网站招商广告语?  网站企业制作流程,用什么语言做企业网站比较好?  如何自定义建站之星网站的导航菜单样式?  制作销售网站教学视频,销售网站有哪些?  大学网站设计制作软件有哪些,如何将网站制作成自己app?  如何在服务器上三步完成建站并提升流量?  建站之星如何助力网站排名飙升?揭秘高效技巧 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。