Python上下文管理器全实例详解


Posted in Python onNovember 12, 2019

Python上下文管理器

简介

最近用到这个,仔细了解了一下,感觉是十分有用的,记录一下

使用场景

当我们需要获取一个临时打开的资源,并在使用完毕后进行资源释放和异常处理,利用try-catch语句可以完成,举个例子。

打开文件:

f = None
try:
 print("try")
 f = open("__init__.py", "r")
 print(f.read())
except Exception as e:
 print("exception")
finally:
 if f:
  print("finally")
  f.close()

利用上下文管理器:

class OpenHandle:

 def __init__(self, filename, mode):
  self.filename = filename
  self.mode = mode

 def __enter__(self):
  self.f = open(self.filename, self.mode)
  return self.f

 def __exit__(self, exc_type, exc_val, exc_tb):
  if exc_type:
   print("exception")
  else:
   print("normal")
  self.f.close()

with OpenHandle("book.txt", "r") as f:
 print(f.read())

这样可以利用with-as语句改写代码,让程序员关注业务主流程,去掉对于资源的获取和关闭这些重复操作。提升代码的可读性。好处很大。

执行顺序

执行顺序是理解这种写法的关键:

  • 初始化,执行handle的__init__()
  • __enter__()方法,获取资源对象,返回给as后的变量
  • 业务代码逻辑
  • __exit__方法,传入3个参数,异常类型,异常对象,调用栈对象,无异常都为None
  • 抛出异常或者正常结束

函数式上下文管理器

利用from contextlib import contextmanager这个装饰器可以将函数装饰为上下文管理器,其实这个装饰背后也是返回一个实现了__enter__和__exit__方法的类

from contextlib import contextmanager

@contextmanager
def managed_resource(*args, **kwds):
 # Code to acquire resource, e.g.:
 resource = acquire_resource(*args, **kwds)
 try:
  yield resource
 finally:
  # Code to release resource, e.g.:
  release_resource(resource)

>>> with managed_resource(timeout=3600) as resource:
...  # Resource is released at the end of this block,
...  # even if code in the block raises an exception

模板代码

sqlalchemy会话上下文管理器

利用这个管理sqlalchemy会话对象的获取和释放,控制事务是再合适不过了

class DbTransaction:

 def __init__(self, session_maker):
  self.session_maker = session_maker

 def __enter__(self):
  self.session = self.session_maker()
  return self.session

 def __exit__(self, exc_type, exc_val, exc_tb):
  if exc_type:
   self.session.rollback()
  else:
   self.session.commit()
  self.session.close()
  return False if exc_type else True

以上就是全部相关知识点,感谢大家的学习和对三水点靠木的支持。

Python 相关文章推荐
python判断图片宽度和高度后删除图片的方法
May 22 Python
Python中执行存储过程及获取存储过程返回值的方法
Oct 07 Python
Python决策树和随机森林算法实例详解
Jan 30 Python
使用python编写监听端
Apr 12 Python
详解django.contirb.auth-认证
Jul 16 Python
kali中python版本的切换方法
Jul 11 Python
解决Django连接db遇到的问题
Aug 29 Python
python 实现dict转json并保存文件
Dec 05 Python
python实现局域网内实时通信代码
Dec 22 Python
tensorflow生成多个tfrecord文件实例
Feb 17 Python
Django多层嵌套ManyToMany字段ORM操作详解
May 19 Python
Django 解决由save方法引发的错误
May 21 Python
python3-flask-3将信息写入日志的实操方法
Nov 12 #Python
Python API自动化框架总结
Nov 12 #Python
python的scipy实现插值的示例代码
Nov 12 #Python
python对验证码降噪的实现示例代码
Nov 12 #Python
Python FTP文件定时自动下载实现过程解析
Nov 12 #Python
详解在python操作数据库中游标的使用方法
Nov 12 #Python
如何分离django中的媒体、静态文件和网页
Nov 12 #Python
You might like
php桌面中心(三) 修改数据库
2007/03/11 PHP
php通过strpos查找字符串出现位置的方法
2015/03/17 PHP
用PHP生成excel文件到指定目录
2015/06/22 PHP
PHP模拟post提交数据方法汇总
2016/02/16 PHP
PHP无限极分类函数的实现方法详解
2017/04/15 PHP
laravel-admin 管理平台获取当前登陆用户信息的例子
2019/10/08 PHP
基于javascript的JSON格式页面展示美化方法
2014/07/02 Javascript
实例详解Node.js 函数
2018/06/10 Javascript
angular的输入和输出的使用方法
2018/09/22 Javascript
微信二次分享报错invalid signature问题及解决方法
2019/04/01 Javascript
详解可以用在VS Code中的正则表达式小技巧
2019/05/14 Javascript
JavaScript函数IIFE使用详解
2019/10/21 Javascript
JQuery实现折叠式菜单的详细代码
2020/06/03 jQuery
js实现网页随机验证码
2020/10/19 Javascript
vue data有值,但是页面{{}} 取不到值的解决
2020/11/09 Javascript
详解JavaScript中的链式调用
2020/11/27 Javascript
python中的内置函数getattr()介绍及示例
2014/07/20 Python
Python实现随机生成手机号及正则验证手机号的方法
2018/04/25 Python
朴素贝叶斯Python实例及解析
2018/11/19 Python
python中的tcp示例详解
2018/12/09 Python
Python随机函数库random的使用方法详解
2019/08/21 Python
Python实现打印实心和空心菱形
2019/11/23 Python
python给指定csv表格中的联系人群发邮件(带附件的邮件)
2019/12/31 Python
python字符串判断密码强弱
2020/03/18 Python
Pytorch环境搭建与基本语法
2020/06/03 Python
keras的三种模型实现与区别说明
2020/07/03 Python
Canvas获取视频第一帧缩略图的实现
2020/11/11 HTML / CSS
函授毕业生的自我鉴定
2013/11/26 职场文书
宣传保护环境的公益广告词
2014/03/13 职场文书
网站推广策划方案
2014/06/04 职场文书
部门活动策划方案
2014/08/16 职场文书
2015年幼儿园中班下学期工作总结
2015/05/22 职场文书
JavaScript中关于预编译、作用域链和闭包的理解
2021/03/31 Javascript
Java Spring 控制反转(IOC)容器详解
2021/10/05 Java/Android
使用vue判断当前环境是安卓还是IOS
2022/04/12 Vue.js
windows server2008 开启端口的实现方法
2022/06/25 Servers