上下文管理器

上下文管理器是实现了上下文管理协议的对象,其特有的语法是“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. CH32V307以太网(芯片内部10M)

    用过WCH的CH579M或者CH563的话,就会发现CH32V307这个自带的10M以太网代码编写与前两颗芯片流程十分相似.部分区别就在于初始化方面. 代码流程依旧按照 初始化--->等待PHY ...

  2. [python] Python二维码生成器qrcode库入门

    Python二维码生成器qrcode库入门 qrcode是二维码生成的Python开源库,官方地址为python-qrcode.所有代码见:Python-Study-Notes. 文章目录 Pytho ...

  3. [R语言] WGCNA入门教程

    文章目录 wgcna入门-雌性小鼠肝脏表达数据的网络分析:寻找与体重有关的模块 1 数据输入和清洗 1.1 加载基因表达数据 1.2 数据清洗 1.3 加载临床特征数据 2 建设表达网络与模块检测 2 ...

  4. kafka详解(04) - kafka监控 可视化工具

    kafka详解(04) - kafka监控 可视化工具 Kafka监控Eagle 1)修改kafka启动命令 修改kafka-server-start.sh命令中 if [ "x$KAFKA ...

  5. GC耗时高,原因竟是服务流量小?

    原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处. 简介 最近,我们系统配置了GC耗时的监控,但配置上之后,系统会偶尔出现GC耗时大于1s的报警,排查花了一些力气,故在这里 ...

  6. lwl-resume 个人简历编辑使用说明

    LWL RESUME 是一个简洁.可自定义生成pdf的在线简历编辑工具! 如果你喜欢这种简约格式的简历风格,可以尝试用它来编辑简历 . 注意事项 不支持手机端编辑!请务必使用最新版Chrome(谷歌浏 ...

  7. BC7-牛牛的字符矩形

    题目描述 牛牛尝试用键盘读入一个字符,然后在屏幕上显示用这个字符组成的 3*3 的矩形. 输入描述 一行读入一个 char 类型的字符. 输出描述 输出这个字符组成的 3*3 矩形. 示例 1 输入: ...

  8. 【开源】libserial_parse_text:命令行解析的基础库

    借助五一假期,写了一个命令行解析的基础库,一般可用于串口命令解析.TCP命令解析等等. 具有以下几种特点: 不涉及到具体硬件, 纯软件协议,与具体硬件分离. 支持不定长命令行,逐个字符解码,可以支持不 ...

  9. 关于Spring的IoC容器,你了解多少

    IoC的基本概念   Ioc的全称是Inversion of Control,中文通常翻译为"控制反转".好莱坞原则"Dont't call us, we will ca ...

  10. 数字游戏(NOIP 2003 PJT2)

    一 原始数据处理 1.输入数据得到a[1]~a[n],复制扩展a[n+1]~a[2*n],以便处理不同点为起点出发. cin>>n>>m; for(int i=1;i<= ...