上下文管理器及with的相关总结
什么是上下文管理器
基本语法
with EXPR as VAR:
BLOCK
概念
- 上下文表达式:with open('test.txt') as f:
- 上下文管理器:open('test.txt')
- f 不是上下文管理器,应该是资源对象
作用
- with语句就是简洁版的try/finally语句
- 代码块前后必然会执行的内容
原理
上下文管理器是内部实现了__enter__和__exit__方法的对象
class Foo:
def __init__(self):
print("实例化一个对象")
def __enter__(self):
print("进入")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print("退出")
return True
def func(self):
print("被执行的方法")
with Foo() as f:
f.func()
>>>实例化一个对象
>>>进入
>>>被执行的方法
>>>退出
__enter__
方法说明上下文管理器的__enter__方法是可以带返回值的,默认返回None,这个返回值通过with...as...中的 as 赋给它后面的那个变量,所以 with EXPR as VAR 就是将EXPR对象__enter__方法的返回值赋给 VAR,VAR可以是单个变量,或者由“()”括起来的元组(不能是仅仅由“,”分隔的变量列表,必须加“()”)。 with...as...并非固定组合,单独使用with...也是可以的,上下文管理器的__enter__方法还是正常执行,只是这个返回值并没有赋给一个变量,with下面的代码块也不能使用这个返回值。
__exit__
方法说明上下文管理器的__exit__方法接收3个参数exc_type、exc_val、exc_tb,如果代码块BLOCK发生了异常e并退出,这3个参数分别为type(e)、str(e)、e.__traceback__,否则都为None。 同样__exit__方法也是可以带返回值的,这个返回值应该是一个布尔类型True或False,默认为None(即False)。如果为False,异常会被抛出,用户需要进行异常处理。如果为True,则表示忽略该异常。
上下文管理器的使用
异常处理
处理异常,通常都是使用 try...execept..
来捕获处理的。这样做一个不好的地方是,在代码的主逻辑里,会有大量的异常处理代理,这会很大的影响我们的可读性。
好一点的做法呢,可以使用 with
将异常的处理隐藏起来。
仍然是以上面的代码为例,我们将1/0
这个一定会抛出异常的代码
写在 func
里
__exit__
函数的三个参数
- exc_type:异常类型
- exc_val:异常值
- exc_tb:异常的错误栈信息
class Foo:
def __init__(self):
print("实例化一个对象")
def __enter__(self):
print("进入")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
import traceback
if exc_val:
print("异常类型:",exc_type)
print("异常值:",exc_val)
traceback.print_tb(exc_tb,-1)#打印最开始的错误信息,可设置错误栈数以及写入文件
print("退出")
return True
def func(self):
print(1 / 0)
print("被执行的方法")
with Foo() as f:
f.func()
---------------------------------------------
实例化一个对象
进入
File "F:/PyProgram/test98/test1.py", line 62, in func
print(1 / 0)
异常类型: <class 'ZeroDivisionError'>
异常值: division by zero
退出
资源管理
在我们日常使用场景中,经常会操作一些资源,比如文件对象、数据库连接、Socket连接等,资源操作完了之后,不管操作的成功与否,最重要的事情就是关闭该资源,否则资源打开太多而没有关闭,程序会报错 。
常见的上下文管理器
file
decimal.Context
thread.LockType
threading.Lock
threading.RLock
threading.Condition
threading.Semaphore
threading.BoundedSemaphore
理解并使用 contextlib
Python还提供了一个contextmanager装饰器,允许用户将一个生成器定义为上下文管理器,该装饰器将生成器中的代码通过yield语句分成两部分,yield之前的代码为__enter__
方法,yield之后的代码为__exit__
方法,yield的返回值即__enter__
方法的返回值,用于赋给as后的变量。
实现资源管理
import contextlib
@contextlib.contextmanager
def open_func(file_name):
# __enter__方法
print('open file:', file_name, 'in __enter__')
file_handler = open(file_name, 'r')
# 【重点】:yield
yield file_handler
# __exit__方法
print('close file:', file_name, 'in __exit__')
file_handler.close()
return
with open_func('userinfo.txt') as file_in:
for line in file_in:
print(line)
实现异常捕获
import contextlib
import traceback
import sys
@contextlib.contextmanager
def open_func(file_name):
# __enter__方法
print('open file:', file_name, 'in __enter__')
file_handler = open(file_name, 'r')
try:
yield file_handler
except Exception as exc:
exc_type, exc_val, exc_tb = sys.exc_info()
print("异常类型:", exc_type)
print("异常值:", exc_val)
traceback.print_tb(exc_tb, -1)
print('the exception was thrown')
finally:
print('close file:', file_name, 'in __exit__')
file_handler.close()
return
with open_func('userinfo.txt') as file_in:
for line in file_in:
print(1/0)
print(line)
上下文管理器及with的相关总结的更多相关文章
- python上下文管理器ContextLib及with语句
http://blog.csdn.net/pipisorry/article/details/50444736 with语句 with语句是从 Python 2.5 开始引入的一种与异常处理相关的功能 ...
- 上下文管理器——with语句的实现
前言 with语句的使用给我们带来了很多的便利,最常用的可能就是关闭一个文件,释放一把锁. 既然with语句这么好用,那我也想让我自己写的代码也能够使用with语句,该怎么实现? 下面具体介绍怎样实现 ...
- (转)Python中的上下文管理器和Tornado对其的巧妙应用
原文:https://www.binss.me/blog/the-context-manager-of-python-and-the-applications-in-tornado/ 上下文是什么? ...
- python 黑魔法 ---上下文管理器(contextor)
所谓上下文 计算机上下文(Context)对于我而言,一直是一个很抽象的名词.就像形而上一样,经常听见有人说,但是无法和现实认知世界相结合. 最直观的上下文,莫过于小学的语文课,经常会问联系上下文,推 ...
- Python上下文管理器(Context managers)
上下文管理器(Context managers) 上下文管理器允许你在有需要的时候,精确地分配和释放资源. 使用上下文管理器最广泛的案例就是with语句了.想象下你有两个需要结对执行的相关操作,然后还 ...
- python中的with的用法,上下文管理器
with是从Python2.5引入的一个新的语法,它是一种上下文管理协议,目的在于从流程图中把 try,except 和finally 关键字和 资源分配释放相关代码统统去掉,简化try….excep ...
- Python 上下文管理器模块--contextlib
在 Python 处理文件的时候我们使用 with 关键词来进行文件的资源关闭,但是并不是只有文件操作才能使用 with 语句.今天就让我们一起学习 Python 中的上下文管理 contextlib ...
- Python核心技术与实战——二一|巧用上下文管理器和with语句精简代码
我们在Python中对于with的语句应该是不陌生的,特别是在文件的输入输出操作中,那在具体的使用过程中,是有什么引伸的含义呢?与之密切相关的上下文管理器(context manager)又是什么呢? ...
- Python进阶——什么是上下文管理器?
在 Python 开发中,我们经常会使用到 with 语法块,例如在读写文件时,保证文件描述符的正确关闭,避免资源泄露问题. 你有没有思考过, with 背后是如何实现的?我们常常听到的上下文管理器究 ...
随机推荐
- python pytesseract——3步识别验证码的识别入门
验证码识别是个大工程,但入门开始只要3步.需要用到的库PIL.pytesserac,没有的话pip安装.还有一个是tesseract-ocr 下载地址:https://sourceforge.net/ ...
- 使用 Jenkins 与 Sonar 集成对代码进行持续检测
SonarQube 与 Jenkins 简介 SonarQube是 一个开源的代码质量分析平台,便于管理代码的质量,可检查出项目代码的漏洞和潜在的逻辑问题.同时,它提供了丰富的插件,支持多种语言的检测 ...
- Windows下如何调试驱动程序
Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html 一.配置Windbg使用双机调试 win10中“windbg+vm ...
- Mint(Linux)系统设置优化及其常用软件安装笔记
LInux /home下中文目录如何修改成英文? 打开终端,在终端中输入命令: export LANG=en_US xdg-user-dirs-gtk-update 跳出对话框询问是否将目录转化为英文 ...
- QR 码详解(下)
快速响应矩阵码(下) 书接上回,继续下半场. 纠错码 QR 码采用纠错算法生成一系列纠错码字,添加在数据码字序列之后,使得符号可以在遇到损坏时可以恢复.这就是为什么二维码即使有残缺也可以扫出来.没有残 ...
- 重磅发布 | 全球首个云原生应用标准定义与架构模型 OAM 正式开源
作者: OAM 项目负责人 导读:2019 年 10 月 17 日,阿里巴巴合伙人.阿里云智能基础产品事业部总经理蒋江伟(花名:小邪)在 Qcon 上海重磅宣布,阿里云与微软联合推出开放应用模型 Op ...
- MOV与LEA
MOV 格式:MOV dest, src 作用:赋值,且不改变标记位的值 特点:可以从寄存器到寄存器.从立即数到寄存器.从存储单元到寄存器.从立即数到储存单元.从寄存器到存储单元.从寄存器或存储单元到 ...
- Flask中的数据连接池
pymsql链接数据库 import pymysql conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd=' ...
- Vue 全家桶,深入Vue 的世界
内容简介: Vue 实例上的属性 Vue 生命周期 Vue 数据绑定 computed 计算属性 watch 监听器 Vue 组件 Vue 组件 extend Vue 组件高级属性 Vue 的rend ...
- Spring Boot 入门(七):集成 swagger2
本片文章是基于前一篇写的,<Spring Boot 入门(六):集成 treetable 和 zTree 实现树形图>,本篇主要介绍了spring boot集成swagger2.关于swa ...