Python with语句和过程抽取思想


Posted in Python onDecember 23, 2019

python中的with语句使用于对资源进行访问的场合,保证不管处理过程中是否发生错误或者异常都会执行规定的__exit__(“清理”)操作,释放被访问的资源,比如有文件读写后自动关闭、线程中锁的自动获取和释放等。

与python中with语句有关的概念有:上下文管理协议、上下文管理器、运行时上下文、上下文表达式、处理资源的代码段。

with语句的应用场景

  编程中有很多操作都是配套使用的,这种配套的流程可以称为计算过程,Python语言为这种计算过程专门设计了一种结构:with语句。比如文件处理就是这类计算过程的典型代表。

使用with语句前后对比

没有使用with语句之前,我们是这样打开一个文件的:

try:
 # 1. [进入]
 f = open('a.txt', 'r', encoding="utf-8")
 # 2. [执行]
 print(f.read())
finally:
 if f:
  # 3. [退出]
  f.close()

python操作文件的流程一般就是这三步:

1.[进入]用只读方式打开文件

如果文件不存在,open()函数就会抛出一个IOError的错误,并且给出错误码和详细的信息告诉你文件不存在

2.[执行]读取文件内容

如果文件打开成功,接下来,调用read()方法可以一次读取文件的全部内容,Python把内容读到内存,用一个str对象表示

3.[退出]关闭打开的文件

文件使用完毕后必须关闭,因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的

思考为什么关闭文件操作一定要放在finallly语句里?

  由于文件读写时都有可能产生IOError,一旦出错,后面的f.close()就不会调用。所以,为了保证无论是否出错都能正确地关闭文件,我们可以使用try ... finally来实现。

发现共性:

我们发现其实这种过程化的语句有共性,比如说在进去一个片段必须做某种超赞,处理工作又需要执行一个结束操作。比如上面的这段代码:

finally:
 if f:
  f.close()

就可以做一个封装。

使用with语句后,我们是这样打开一个文件的:

with open("a.txt", "r", encoding="utf-8") as f:
 print(f.read())

这个with语句和前面的try ... finally结构是一样的,但是代码更佳简洁,并且不必调用f.close()方法。

with语句的执行原理

从解释器的角度去理解with语句执行流程。

with语句的基本形式是:

with 表达式 as 变量:
 语句块

  这样的一段代码可以称为一个上下文(context),在执行with语句时,解释器会先求出表达式的值,这个值(对象)是一个上下文管理器,并且假设这个对象拥有如下类的构造方法:

def __enter__():
  # 描述进入上下文的动作
  pass

 def __exit__():
  # 描述退出上下文的动作
  pass

with语句在求出这个上下文管理器对象之后,自动执行进入方法,并将这个对象的返回值赋值于 as 之后的变量,然后执行语句块。然后在退出上下文前,自动执行对象的退出方法

python系统和标准库的一些类型定义了这对操作,可以直接用于with语句。比如文件对象就直接支持这一对操作,因此可以用在with语句的头部。

如果你也有类似的计算过程需要抽取出来,那么可以自定义一个类,并且包含进入、退出方法。

自定义open函数

自己实现才发现,使用装饰器和生成器就能很好的解决这个问题,不需要用到类构造方法来实现;

import contextlib # 引入上下文管理包

@contextlib.contextmanager # 给函数引入装饰器
def myopen(dir, mode):
 print("开始")
 f = open(dir, mode, encoding='utf-8')
 try: # 上文
  yield f
 finally: # 下文
  print("结束")
  f.close()

with myopen("a.txt", 'r') as fobj: # 把try中的yield中的f赋值给fobj
 # with会将with后面的函数中的yield赋值给fobj
 for i in fobj:
  print(i)
  # 等待上面的循环结束后,才最终执行finally的代码,所以这就是上下文管理

输出:

开始
hello,我是a.txt的第1行文字。
结束

总结

打开文件读写、用pickle包完成数据的存储、恢复的操作,都非常适合使用with语句。

pickle包的使用案例:

try:
 with open("phone.pickle", "wb") as outf:
  pickle.dump("13193388105", outf)
except:
 print("file have errow.")


try:
 with open("phone.pickle", "rb") as outf:
  data = pickle.load(outf)
  print(type(data))
  print(data)
except:
 print("file have errow.")

我总结了一下使用with语句的优点:

  • 采用with语句的代码更简洁
  • 防止因为忘记写f.close()而引发的错误
  • 一个对象的操作有进入、退出过程可以抽取出来,并做成自动化执行

总结

以上所述是小编给大家介绍的Python with语句和过程抽取思想,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Python 相关文章推荐
Python 实现在文件中的每一行添加一个逗号
Apr 29 Python
Python 给定的经纬度标注在地图上的实现方法
Jul 05 Python
Python对接 xray 和微信实现自动告警
Sep 17 Python
python将三维数组展开成二维数组的实现
Nov 30 Python
Python如何基于selenium实现自动登录博客园
Dec 16 Python
Python3 操作 MySQL 插入一条数据并返回主键 id的实例
Mar 02 Python
Jupyter notebook无法导入第三方模块的解决方式
Apr 15 Python
Python matplotlib读取excel数据并用for循环画多个子图subplot操作
Jul 14 Python
从python读取sql的实例方法
Jul 21 Python
Python如何在单元测试中给对象打补丁
Aug 03 Python
社区版pycharm创建django项目的方法(pycharm的newproject左侧没有项目选项)
Sep 23 Python
简述python&pytorch 随机种子的实现
Oct 07 Python
python每5分钟从kafka中提取数据的例子
Dec 23 #Python
Python彻底删除文件夹及其子文件方式
Dec 23 #Python
win10下python2和python3共存问题解决方法
Dec 23 #Python
py-charm延长试用期限实例
Dec 22 #Python
python分布式计算dispy的使用详解
Dec 22 #Python
使用python实现哈希表、字典、集合操作
Dec 22 #Python
浅析Python数字类型和字符串类型的内置方法
Dec 22 #Python
You might like
短波的认识
2021/03/01 无线电
表单复选框向PHP传输数据的代码
2007/11/13 PHP
php 计算两个时间戳相隔的时间的函数(小时)
2009/12/18 PHP
PHP数组函数array_multisort()用法实例分析
2016/04/02 PHP
JSON 数据格式介绍
2012/01/13 Javascript
如何使用Jquery获取Form表单中被选中的radio值
2013/08/09 Javascript
JQuery伸缩导航练习示例
2013/11/13 Javascript
Javascript 按位与运算符 (&)使用介绍
2014/02/04 Javascript
基于NodeJS的前后端分离的思考与实践(六)Nginx + Node.js + Java 的软件栈部署实践
2014/09/26 NodeJs
js实现tab切换效果实例
2015/09/16 Javascript
JavaScript代码实现禁止右键、禁选择、禁粘贴、禁shift、禁ctrl、禁alt
2015/11/17 Javascript
JavaScript事件代理和委托详解
2016/04/08 Javascript
javascript 动态样式添加的简单实现
2016/10/11 Javascript
利用angular.copy取消变量的双向绑定与解析
2016/11/25 Javascript
webpack2.0配置postcss-loader的方法
2017/08/17 Javascript
vue中component组件的props使用详解
2017/09/04 Javascript
通过jquery toggleClass()属性制作文章段落更改背景颜色
2018/05/21 jQuery
Node.js中的不安全跳转如何防御详解
2018/10/21 Javascript
jQuery+Datatables实现表格批量删除功能【推荐】
2018/10/24 jQuery
微信小程序常用赋值方法小结
2019/04/30 Javascript
如何用原生js写一个弹窗消息提醒插件
2019/05/24 Javascript
vue  elementUI 表单嵌套验证的实例代码
2019/11/06 Javascript
JavaScript HTML DOM 元素 (节点)新增,编辑,删除操作实例分析
2020/03/02 Javascript
[04:10]2018年度CS GO玩家最喜爱的主播-完美盛典
2018/12/16 DOTA
通过python爬虫赚钱的方法
2019/01/29 Python
Python获取当前脚本文件夹(Script)的绝对路径方法代码
2019/08/27 Python
DJango的创建和使用详解(默认数据库sqlite3)
2019/11/18 Python
pytorch的batch normalize使用详解
2020/01/15 Python
matplotlib阶梯图的实现(step())
2021/03/02 Python
英国顶级水晶珠宝零售商之一:Tresor Paris
2019/04/27 全球购物
美国优质宠物用品购买网站:Muttropolis
2020/02/17 全球购物
党员公开承诺书和承诺事项
2014/03/25 职场文书
入党自荐书范文
2015/03/05 职场文书
中学政教处工作总结
2015/08/13 职场文书
创业计划书之冷饮店
2019/09/27 职场文书
Golang 语言控制并发 Goroutine的方法
2021/06/30 Golang