什么是上下文管理器?

上下文管理器是在Python2.5之后加入的功能,可以在方便的需要的时候比较精确地分配和释放资源, with便是上下文管理器的最广泛的应用

with open("test/test.txt","w") as f:f.write("hello")

这上会比使用try:...finally:f.close方便的多.

首先引出为什么要使用上下文管理器:我们的代码图如下

通过上图代码我们可以发现,我们每次都要进行db.session.commit()我们可能在项目的很多地方都会使用到,如果我们每次都要写try except 然后在里面回滚,这些重复的代码我们尽可能的要去避免。下面我们就来解决这个问题。

我们先来回顾一下上下文管理器-with

类中有两个特殊的魔术方法: 
__enter__: with语句中的代码块执行前, 会执行__enter__, 返回的值将赋值给with句中as后的变量. 
__exit__: with语句中的代码块执行结束或出错, 会执行_exit__

如果我们要定义上下文管理器,就需要在这类里面定义__enter____exit__这两个方法。

有没有什么简化的方法不需要我们直接定义__enter__和__exit__呢?

python提供了一个装饰器叫@contextmanager,是位于contextlib模块下的。

借助contextmanager装饰器,我们可以简化MyResource的定义

现在我们不要__enter__和__exit__方法,只保留核心方法query(),注意我们只是不想在定义__enter__和__exit__这两个方法,但是他们里面所执行的语句我们还是需要实现的。在进入上下文管理器的时候打印__enter__里面的方法,在退出的时候打印__exit__里面的方法。

所以最终的代码如上图所示。

被装饰器装饰的函数分为三部分: 
with语句中的代码块执行前执行函数中yield之前代码 
yield返回的内容复制给as之后的变量 
with代码块执行完毕后执行函数中yield之后的代码

大家都说利用@contextmanager这个内置的装饰器可以减化上下文管理器的定义,但是我不这样认为。但是这样写有一个非常的好处,就是使用@contextmanager的好处就是给了我们一个机会,让我们把原来不是上下文管理器的类变成了上下文管理器,假如这个MyResource的类不是我们自己编写的,比如说是flask提供给我们的或者是第三方类库提供给我们的,我们去改变源码在里面加__enter__和__exit__方法是不合适的,但是我们却可以在MyResource的类的外部使用@contextmanager把MyResource包装成一个上下文管理器。

例如:

注意下图第三方的SQLAlchemy的名字被我们as成了_SQLAlchemy,这样SQLAlchemy就是父类的子类的。

我们如何为一个第三方的类库新增加一个方法呢?我们可以新建一个子类,然后继承SQLAlchemy

这样我们就可以把代码变成下面这样了

对比之前的是不是简单了呢?(下图为未使用上下文管理器之前的代码),上图仅仅一个with就解决了try except的繁琐。


扩展知识点:

现在我们想打印一本书的名字,但是每一次前后都要自己加书名号太烦了,书名是我们从数据库中查出来的,但是我们在数据库中保存是不会加书名号的,现在我们取出来显示的时候想加书名号,那么我们使用@contextmanager解决

因为我们的with后面没有as,所以我们不需要yield返回任何的结果,这里只写一个yield是可以的。

但是因为有换行,那么我们就在后面加上end=''就行啦

这里的用法就是@contextmanager的另一种用法,和上下文管理器是没有关系的。


python使用@contextmanager来定义上下文管理器(一篇文章,彻底明白!码文并茂,简单明了)和 yield 和 __enter__ 和 __exit__相关推荐

  1. python上下文是什么_(1条消息)python使用@contextmanager来定义上下文管理器(一篇文章,彻底明白!码文并茂,简单明了)...

    什么是上下文管理器? 上下文管理器是在Python2.5之后加入的功能,可以在方便的需要的时候比较精确地分配和释放资源, with便是上下文管理器的最广泛的应用 with open("tes ...

  2. python中的with上下文管理器

    with 语句 with 语句是 Pyhton 提供的一种简化语法,确保不管使用过程中是否发生异常都会执行必要的"清理"操作,释放资源. 在没有学习with的句法之前,通常我们都是 ...

  3. Python基础教程:上下文管理器 context manager(with...as...)

    一.概念 上下文管理器:就是实现了上下文管理协议的对象.主要用于保存和恢复各种全局状态,关闭文件等.上下文管理器本身是一种装饰器. 上下文允许可以自动的开始和结束一些和事情.例如当利用with-as打 ...

  4. python with关键字_完全理解Python关键字with与上下文管理器

    如果你有阅读源码的习惯,可能会看到一些优秀的代码经常出现带有 "with" 关键字的语句,它通常用在什么场景呢?今天就来说说 with 和 上下文管理器. 对于系统资源如文件.数据 ...

  5. Python: try finally 与 上下文管理器简介

    2019独角兽企业重金招聘Python工程师标准>>> 用 Python 做一件很平常的事情: 打开文件, 逐行读入, 最后关掉文件; 进一步的需求是, 这也许是程序中一个可选的功能 ...

  6. python 多态 锁_python 上下文管理器,多态,数据锁定与自省,

    python 上下文管理器,多态,数据锁定与自省, 前文课题 通过装饰器来实现单例模式 通过类实现一个通用装饰器,皆可以装饰函数也可装饰类,即可有参也可无参 描述 new str repr call ...

  7. python 什么是上下文管理器(ContextManager)?

    上下文是 context 直译的叫法,在程序中用来表示代码执行过程中所处的前后环境.上下文管理器中有 enter 和 exit 两个方法,以with为例子,enter 方法会在执行 with 后面的语 ...

  8. python语言使用什么语句实现上下文管理协议_Python 上下文管理器

    上下文管理器 在使用Python编程中,可以会经常碰到这种情况:有一个特殊的语句块,在执行这个语句块之前需要先执行一些准备动作:当语句块执行完成后,需要继续执行一些收尾动作. 例如:当需要操作文件或数 ...

  9. Python高级——with上下文管理器

    with上下文管理器 任何实现了 enter() 和 exit() 方法的对象都可称之为上下文管理器,上下文管理器对象可以使用 with 关键字. 如果一个一个文件使用普通方式打开: def m1() ...

最新文章

  1. 零欧姆电阻在电路上的作用
  2. 实战|基于图割算法的木材表面缺陷图像分析
  3. 【NLP-NER】什么是命名实体识别?
  4. web默认字体最佳实践
  5. C# datetime 操作
  6. plsql轻量版记录类型2
  7. IDEA 正式版终于支持中文版和 JDK 直接下载了(太方便了)附介绍视频
  8. metasploit mysql_Metasploit渗透测试:选择模块
  9. android监听键盘的隐藏,Android监听软键盘的显示和隐藏
  10. 连接linux常用的工具
  11. HDU - 1247 (字典树水题)
  12. 菜鸟学python集训云_菜鸟学Python,老司机给新手总结的Python实战问题
  13. 词法分析器【编译原理】
  14. 联想笔记本卸载McAfee
  15. flask中for循环
  16. DBeaver解决连接Oracle之后出现库名为数字问题
  17. MySQL数据库 - 复杂查询(二)第二关
  18. C# 鼠标悬浮mouseHover事件的添加 实现鼠标悬浮在按钮或者控件 显示相关的帮助信息
  19. 浏览器如何使用HTTP防止ip限制
  20. 什么是网站可访问性?

热门文章

  1. python反编译-以2048小游戏为例
  2. 华为OD机试真题 Java 实现【去除多余空格】【2022.11 Q4 新题】
  3. 迅雷一度曾打不开torrent文件.
  4. LINUX 查询已安装的软件信息
  5. php file_put_contents 换行追加,PHP中file_put_contents追加和换行的实现方法
  6. windows下查看端口被占用问题的解决
  7. 王者荣耀盒子App数据爬取
  8. Codeforces Educational Round #42
  9. override关键字
  10. 网传阿里将裁两万人,大部分是Java开发……