python中的上下文管理器以及python内建模块contextlib的contextmanager方法
上下文管理器
上下文管理器是实现了上下文管理协议的对象,其特有的语法是“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方法的更多相关文章
- (转)Python中的上下文管理器和Tornado对其的巧妙应用
原文:https://www.binss.me/blog/the-context-manager-of-python-and-the-applications-in-tornado/ 上下文是什么? ...
- Python中的上下文管理器和with语句
Python2.5之后引入了上下文管理器(context manager),算是Python的黑魔法之一,它用于规定某个对象的使用范围.本文是针对于该功能的思考总结. 为什么需要上下文管理器? 首先, ...
- 深入理解 Python 中的上下文管理器
提示:前面的内容较为基础,重点知识在后半段. with 这个关键字,对于每一学习Python的人,都不会陌生. 操作文本对象的时候,几乎所有的人都会让我们要用 with open ,这就是一个上下文管 ...
- python中实现上下文管理器的两种方法
上下文管理器: python中实现了__enter__和__exit__方法的对象就可以称之为上下文管理器 实现方法一举例: def File(object): def __init__(self, ...
- Python中的上下文管理器(contextlib模块)
上下文管理器的任务是:代码块执行前准备,代码块执行后收拾 1 如何使用上下文管理器: 打开一个文件,并写入"hello world" filename="my.txt&q ...
- python中利用上下文管理器来实现mysql数据库的封装
from pymysql import connect class DB(object): def __init__(self, password, database): # 1.连接数据库 self ...
- python中的上下文管理器
刚刚看了vamei大神的上下文管理器博客,理解如下: 其实我自己经常用到上下文管理器,尤其是在打开文件的时候,如果自己比较懒,不想手工打上f.close(),使用上下文管理器就ok拉. 上下文管理器就 ...
- Python - Context Manager 上下文管理器
什么是上下文管理器 官方解释... 上下文管理器是一个对象 它定义了在执行 with 语句时要建立的运行时上下文 上下文管理器处理进入和退出所需的运行时上下文以执行代码块 上下文管理器通常使用 wit ...
- Python深入02 上下文管理器
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 上下文管理器(context manager)是Python2.5开始支持的一种语 ...
- 【Python】【上下文管理器】
"""#[备注]#1⃣️try :仅当try块中没有异常抛出时才运行else块.#2⃣️for:仅当for循环运行完毕(即for循环没有被break语句终止)才运行els ...
随机推荐
- Isaac Sim 机器人仿真器介绍、安装与 Docker [1]
前言与参考 此文书写于: January 6, 2023, 更新于 January 6, 2023 :可能会随着时间的变化 此教程会有过时概念哦 Isaac Sim 相关参考链接: 官方文档地址 官方 ...
- 【SpringBoot实战专题】「开发实战系列」从零开始教你舒服的使用RedisTemplate操作Redis数据
SpringBoot快速操作Redis数据 在SpringBoot框架中提供了spring-boot-starter-data-redis的依赖组件进行操作Redis服务,当引入了该组件之后,只需要配 ...
- 我曾经用“UC震惊部”震碎了很多人的三观
Hi,欢迎大家在有空的时候做客[江涛学编程],这里是2023年的第9篇原创文章,今天写的这篇是当事人对昨天上热搜的统一回复. 我没有曾经跨过山河大海,我也没有曾经穿越人山人海,但我曾经用"U ...
- .NetCore下基于FreeRedis实现的Redis6.0客户端缓存之缓存键条件优雅过滤
前言 众所周知内存缓存(MemoryCache)数据是从内存中获取,性能表现上是最优的,但是内存缓存有一个缺点就是不支持分布式,数据在各个部署节点上各存一份,每份缓存的过期时间不一致,会导致幻读等各种 ...
- 算法之倍增和LCA:论点与点之间的攀亲戚
前言 我们在做树形题和图论题时常常遇到这样的问题:要求求出树上两点间的最近公共祖先(LCA),这时我们该怎么办? 思路一:暴力爬爬爬-- 很容易想到让两个点都往上爬,啥时候相遇了就是他们的最近公共祖先 ...
- 【Dubbo3终极特性】「流量治理体系」一文教你如何通过Dubbo-Admin实现动态进行流量隔离机制
背景信息 如果一个应用有多个版本在线上同时运行,部署在不同环境中,如日常环境和特殊环境,则 可以使用标签路由对不同环境中的不同版本进行流量隔离,将秒杀订单流量或不同渠道订单流量路由到特殊环境,将正常的 ...
- 把KMP算法嚼碎了喂给你吃!(C++)
相信不少人在学数据结构的时候都被KMP算法搞的迷迷糊糊的,原理看的似懂非懂,代码写不出来,或者写出来了也不知道为什么就可以这么写.本文力求尽可能通俗详细的讲解KMP算法,让你不再受到KMP算法的困扰. ...
- JavaScript 检查(Linting)工具的比较
一个好的检查(linting)工具可以确保一个项目遵循编码规范. 让我们来看看四种流行替代方案的特性和优缺点:JSLint , JSHint , JSCS 和 ESLint . JSLint JSLi ...
- 动力节点—day06
常用类 String String表示字符串类型,属于引用数据类型,不属于基本数据类型 在Java中随便使用双引号括起来的都是String对象,例如"abc"."def& ...
- python自动发布-优化版本
import sys import time import os import paramiko from pygments.lexers import shell baseconfig = { &q ...