上下文管理器

上下文管理器是实现了上下文管理协议的对象,其特有的语法是“with …as”。主要用于保存和恢复各种全局状态,关闭文件等,并为try…except…finally提供了一个方便使用的封装。

上下文管理协议具体来说就是在类里面实现以下两个方法:

_enter_(): 从该方法进入运行时上下文,并返回当前对象或者与运行时上下文相关的其他对象。如果with语句有as关键词存在,返回值会绑定在as后的变量上。

_exit_(exc_type, exc_val, exc_tb): 退出运行时上下文,return True 如果 with 执行体有异常,则不会继续向上抛出异常;return Flase 如果 with 执行体有异常,则继续向上抛出异常。如果在执行with语句体时发生异常,那退出时参数会包括异常类型、异常值、异常追踪信息,否则,3个参数都是None。
下面,我们可以自己定义一个类来通过with进行上下文管理:

class MyContextManager:

    def __enter__(self):
print("connect to contextmanager")
return self # return返回的可以是对象,会绑定给as后面的变量 def __exit__(self, exc_type, exc_val, exc_tb):
"""__exit__方法中:
1.如果return False:执行query_data方法有异常,则异常继续往上抛
2.如果return True:执行query_data方法有异常,则异常不会往上抛
"""
print('close the contextmanager')
# return False
return True def query_data(self):
print('query data') with MyContextManager() as m:
m.query_data()

执行以上代码,运行结果如下:

下面,我们在类的query_data方法中增加一个报错的a,当__exit__方法 return True 时,如下:

class MyContextManager:

    def __enter__(self):
print("connect to contextmanager")
return self # return返回的可以是对象,会绑定给as后面的变量 def __exit__(self, exc_type, exc_val, exc_tb):
"""__exit__方法中:
1.如果return False:执行query_data方法有异常,则异常继续往上抛
2.如果return True:执行query_data方法有异常,则异常不会往上抛
"""
print('close the contextmanager')
# return False
return True def query_data(self):
a
print('query data') with MyContextManager() as m:
m.query_data()

运行结果如下:并不会执行 query_data() 方法

当__exit__方法 return False 时,如下:

class MyContextManager:

    def __enter__(self):
print("connect to contextmanager")
return self # return返回的可以是对象,会绑定给as后面的变量 def __exit__(self, exc_type, exc_val, exc_tb):
"""__exit__方法中:
1.如果return False:执行query_data方法有异常,则异常继续往上抛
2.如果return True:执行query_data方法有异常,则异常不会往上抛
"""
print('close the contextmanager')
return False
# return True def query_data(self):
a
print('query data') with MyContextManager() as m:
m.query_data()

运行结果如下:会抛异常,

实际应用示例:

创建一个上下文管理器,这个上下文管理器将会创建一个SQLite数据库连接,当任务处理完毕,将会将其关闭。

import sqlite3

class DataConn:
def __init__(self,db_name):
self.db_name = db_name def __enter__(self):
self.conn = sqlite3.connect(self.db_name)
return self.conn def __exit__(self,exc_type,exc_val,exc_tb):
self.conn.close()
if exc_val:
raise if __name__ == "__main__":
db = "test/test.db"
with DataConn(db) as conn:
cursor = conn.cursor()

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

Python的内建模块 contextlib

对于上下文的管理,python也提供了内建的模块contextlib来实现相同的机制,而且这种通过生成器和装饰器实现的上下文管理器,看起来比with语句和手动实现上下文管理协议更优雅。

from contextlib import contextmanager

class MyContextManager:
def query_data(self):
# a
print('query data') @ contextmanager # 有了contextmanager我们就不需要手动实现enter和exit方法
def make_context_manager():
print('connect to contextmanager')
yield MyContextManager() # yield就相当于return,但是不会结束函数,而是暂时挂起,如果我们后续需要的话,继续调用这个函数,会从上次挂起的地方继续执行
print('close the contextmanager') with make_context_manager() as mc:
mc.query_data()

python中的上下文管理器以及python内建模块contextlib的contextmanager方法的更多相关文章

  1. (转)Python中的上下文管理器和Tornado对其的巧妙应用

    原文:https://www.binss.me/blog/the-context-manager-of-python-and-the-applications-in-tornado/ 上下文是什么? ...

  2. Python中的上下文管理器和with语句

    Python2.5之后引入了上下文管理器(context manager),算是Python的黑魔法之一,它用于规定某个对象的使用范围.本文是针对于该功能的思考总结. 为什么需要上下文管理器? 首先, ...

  3. 深入理解 Python 中的上下文管理器

    提示:前面的内容较为基础,重点知识在后半段. with 这个关键字,对于每一学习Python的人,都不会陌生. 操作文本对象的时候,几乎所有的人都会让我们要用 with open ,这就是一个上下文管 ...

  4. python中实现上下文管理器的两种方法

    上下文管理器: python中实现了__enter__和__exit__方法的对象就可以称之为上下文管理器 实现方法一举例: def File(object): def __init__(self, ...

  5. Python中的上下文管理器(contextlib模块)

    上下文管理器的任务是:代码块执行前准备,代码块执行后收拾 1 如何使用上下文管理器: 打开一个文件,并写入"hello world" filename="my.txt&q ...

  6. python中利用上下文管理器来实现mysql数据库的封装

    from pymysql import connect class DB(object): def __init__(self, password, database): # 1.连接数据库 self ...

  7. python中的上下文管理器

    刚刚看了vamei大神的上下文管理器博客,理解如下: 其实我自己经常用到上下文管理器,尤其是在打开文件的时候,如果自己比较懒,不想手工打上f.close(),使用上下文管理器就ok拉. 上下文管理器就 ...

  8. Python - Context Manager 上下文管理器

    什么是上下文管理器 官方解释... 上下文管理器是一个对象 它定义了在执行 with 语句时要建立的运行时上下文 上下文管理器处理进入和退出所需的运行时上下文以执行代码块 上下文管理器通常使用 wit ...

  9. Python深入02 上下文管理器

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 上下文管理器(context manager)是Python2.5开始支持的一种语 ...

  10. 【Python】【上下文管理器】

    """#[备注]#1⃣️try :仅当try块中没有异常抛出时才运行else块.#2⃣️for:仅当for循环运行完毕(即for循环没有被break语句终止)才运行els ...

随机推荐

  1. C# lock 、 Monitor Wait、Pulse和PulseAll 的区别和用法(转载)

    1.Monitor.Wait方法当线程调用 Wait 时,它释放对象的锁并进入对象的等待队列,对象的就绪队列中的下一个线程(如果有)获取锁并拥有对对象的独占使用.Wait()就是交出锁的使用权,使线程 ...

  2. 工作这么多年,我总结的数据传输对象 (DTO) 的最佳实践

    前言 数据传输对象 (DTO) 是一种设计模式,常用于软件开发不同层或者不同系统之间传输数据.DTO 的主要目的是封装数据并防止它被其他层或系统直接访问或修改.通过遵循一组最佳实践,开发人员可以确保他 ...

  3. echart大坑总结~~echarts呈现的数据刷新不完全/echarts画图时tooltip不会更新

    谨以此文记录在使用echarts中遇到的各种大坑或者小坑,陆续更新加入新坑 欢迎朋友们一起提坑,我们势必绕过它们,愿我们永不再入坑~ 坑一:echarts图表重新赋值数据,图表显示会存在一部分原来的数 ...

  4. 前端基础知识-js(一)个人学习记录

    待补充: https://www.ruanyifeng.com/blog/javascript/ 运行验证: https://www.jsrun.net/new 以下仅为个人理解,如有误请指正,非常感 ...

  5. Vue项目 invalid host header 问题 配置 disableHostCheck:true报错

    项目场景: 解决 Vue 项目 invalid host header 问题disableHostCheck:true报错 问题描述 使用内网穿透时出现 invalid host header 找了好 ...

  6. FLASH-CH32F103替换STM32F103 FLASH快速编程移植说明

    因CH32F103 相对于STM32F103 flash 操作多了快速编程模式,该文档说明主要目的是为了方便客户在原先ST 工程的基础上实现flash 快速编程模式的快速移植. 1.在stm32f10 ...

  7. django框架之drf(部分讲解)

    一.各个视图子类 两个视图基类 五个视图扩展类 九个视图子类----->视图类,不需要额外继承GenericAPIView,只需要继承九个州其中之一,就会有某个或某几个接口 路由 urlpatt ...

  8. Pytest插件pytest-rerunfailures失败重跑

    Pytest插件pytest-rerunfailures失败重跑 安装 pip install pytest-rerunfailures doc https://github.com/pytest-d ...

  9. Git-01 简要介绍

    1 git简介 Git 是一个免费的.开源的分布式版本控制系统,可以快速高效地处理从小型到大型的各种项目. Git 易于学习,占地面积小,性能极快. 它具有廉价的本地库,方便的暂存区域和多个工作流分支 ...

  10. Spring Cloud Openfeign Get请求发生405错误

    kust-retrieve服务 @Resource private AuthFeignService authFeignService; @ApiOperation("获取用户信息" ...