python基础之上下文管理器
2024-10-18 17:20:48
前言
关于计算器运行的上下文的概念,我的理解也不是很深;按我的理解就是程序在运行之前,其所需要的资源,运行环境等都会被序列化,然后加入到CPU的任务队列中,等待调度系统分配时间片执行。下面谈谈python上下文管理器的使用。
系列文章
上下文管理器
- python中最常用的上下文管理器就是文件的打开和关闭了。
with open(filename,'r') as file:
file.read()
原理
- python上下文使用with触发,内部实现了__enter__和__exit__两个魔法方法。
class context(object):
def __init__(self):
print('aaaa')
def __enter__(self):
print('bbbb')
def __exit__(self, exc_type, exc_val, exc_tb):
print('cccc')
# exc_type:异常的类型;
# exc_val:异常的详细信息;
# exc_tb:异常发生的位置;
# 如果没有发生异常,以上三个值都是None
with context() as f:
'''主体逻辑'''
print('xxxx')
# 输出
aaaa
bbbb
xxxx
cccc
- 当使用with触发管理器的时候,先初始化执行__init__得到一个对象,然后执行__enter__方法,再执行主体程序的逻辑,最后执行__exit__方法。
注意
当程序主体逻辑执行完毕退出with语句块或者主体逻辑代码块出现异常,则会自动执行__exit__方法,并且会把对于的异常参数传递进来;如果没有异常,传递的是None。
如果主体逻辑代码发生了错误,但是__exit__函数返回True,则with语句主体逻辑代码块异常不会被抛出,终止程序;如果返回None或者False,异常会被主动raise,并终止程序。
总结上下文管理器的完整的原理
初始化获取一个上下文管理器对象;
加载上下文管理器的 exit() 方法备用;
调用上下文管理器的 enter() 方法;如果有 as f从句,则将 enter() 方法的返回值赋给f;
执行主体逻辑代码块;
调用上下文管理器的 exit() 方法;
python的上下文管理工具contextlib
python内置了对于上下文管理器更优雅的管理方法
import contextlib
@contextlib.contextmanager
def test():
print('aaaaaa')
try:
yield 1
finally:
print('bbbbb')
with test() as f:
print('ccccc')
# 输出
aaaaaa
ccccc
bbbbb
底层简化版的原理
class ContextTest(object):
def __init__(self):
self.f = self.test()
def __enter__(self):
return next(self.f)
def __exit__(self, exc_type, exc_val, exc_tb):
try:
next(self.f)
except StopIteration:
return False
def test(self):
print('aaaaaa')
try:
yield 1
finally:
print('bbbbb')
with ContextTest() as f:
print(f)
print('kkkkkk')
- 说明:
先初始化一个ContextTest上下文管理器对象,得到一个对象的生成器test()
加载上下文管理器的 exit() 方法备用;
调用上下文管理器的 enter() 方法;执行next()方法唤醒test()生成器,执行yield关键字前面的代码;
执行主体逻辑代码;
调用上下文管理器的 exit() 方法;该方法调用next()方法再次唤醒生成器,执行yield关键字后面的代码;
参考
最新文章
- CSS3变形记(上):千变万化的Div
- android:windowSoftInputMode属性详解
- Dumpbin 工具的使用
- Spring MVC 访问静态资源
- input框中的size和maxlength的区别
- TCL校园招聘——软件开发工程师(java) 只招5个。。。
- 《Play for Java》学习笔记(三)template+Message
- POJ3267The Cow Lexicon
- 430的启动,I/O中断
- 【译】 AWK教程指南 附录C-AWK的内建函数
- 【笔记】Linux 和 Unix 作业控制
- Java压缩技术的学习
- 3.C++内联函数,默认参数,占位参数
- rf常用关键字总结
- Vue全家桶(Vue-cli、Vue-route、vuex)
- CodeForces632E 神奇的多重背包
- 区分Web Server和应用服务器
- 判断浏览器是否IE(IE11可用)
- vue中$ref的基本用法
- Python 字典 pop() 方法
热门文章
- 更新 pip &; setuptools
- Codeforces 618D Hamiltonian Spanning Tree(树的最小路径覆盖)
- linux(二) 基本使用命令
- poj 1945 Power Hungry Cows A*
- 【bzoj3589】动态树
- pxp
- Django CRM客户关系管理系统
- 流媒体协议之RTSP详解20170922
- PID控制算法的C语言实现六 抗积分饱和的PID控制算法C语言实现
- Codeforces Round #209 (Div. 2)A贪心 B思路 C思路+快速幂