Python上下文管理器全实例详解
Python上下文管理器
简介
最近用到这个,仔细了解了一下,感觉是十分有用的,记录一下
使用场景
当我们需要获取一个临时打开的资源,并在使用完毕后进行资源释放和异常处理,利用try-catch语句可以完成,举个例子。
打开文件:
f=None try: print("try") f=open("__init__.py","r") print(f.read()) exceptExceptionase: print("exception") finally: iff: print("finally") f.close()
利用上下文管理器:
classOpenHandle: def__init__(self,filename,mode): self.filename=filename self.mode=mode def__enter__(self): self.f=open(self.filename,self.mode) returnself.f def__exit__(self,exc_type,exc_val,exc_tb): ifexc_type: print("exception") else: print("normal") self.f.close() withOpenHandle("book.txt","r")asf: print(f.read())
这样可以利用with-as语句改写代码,让程序员关注业务主流程,去掉对于资源的获取和关闭这些重复操作。提升代码的可读性。好处很大。
执行顺序
执行顺序是理解这种写法的关键:
- 初始化,执行handle的__init__()
- __enter__()方法,获取资源对象,返回给as后的变量
- 业务代码逻辑
- __exit__方法,传入3个参数,异常类型,异常对象,调用栈对象,无异常都为None
- 抛出异常或者正常结束
函数式上下文管理器
利用fromcontextlibimportcontextmanager这个装饰器可以将函数装饰为上下文管理器,其实这个装饰背后也是返回一个实现了__enter__和__exit__方法的类
fromcontextlibimportcontextmanager @contextmanager defmanaged_resource(*args,**kwds): #Codetoacquireresource,e.g.: resource=acquire_resource(*args,**kwds) try: yieldresource finally: #Codetoreleaseresource,e.g.: release_resource(resource) >>>withmanaged_resource(timeout=3600)asresource: ...#Resourceisreleasedattheendofthisblock, ...#evenifcodeintheblockraisesanexception
模板代码
sqlalchemy会话上下文管理器
利用这个管理sqlalchemy会话对象的获取和释放,控制事务是再合适不过了
classDbTransaction: def__init__(self,session_maker): self.session_maker=session_maker def__enter__(self): self.session=self.session_maker() returnself.session def__exit__(self,exc_type,exc_val,exc_tb): ifexc_type: self.session.rollback() else: self.session.commit() self.session.close() returnFalseifexc_typeelseTrue
以上就是全部相关知识点,感谢大家的学习和对毛票票的支持。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。