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环境下安装使用异步任务队列包Celery的基础教程
May 07 Python
flask中主动抛出异常及统一异常处理代码示例
Jan 18 Python
matlab中实现矩阵删除一行或一列的方法
Apr 04 Python
Django后台获取前端post上传的文件方法
May 28 Python
Python解决走迷宫问题算法示例
Jul 27 Python
python定时按日期备份MySQL数据并压缩
Apr 19 Python
pytorch中tensor.expand()和tensor.expand_as()函数详解
Dec 27 Python
Python连接字符串过程详解
Jan 06 Python
Python如何在DataFrame增加数值
Feb 14 Python
在Tensorflow中实现leakyRelu操作详解(高效)
Jun 30 Python
Python内置函数及功能简介汇总
Oct 13 Python
pycharm 关闭search everywhere的解决操作
Jan 15 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/03 冲泡冲煮
PHP 应用程序的安全 -- 不能违反的四条安全规则
2006/11/26 PHP
探讨PHP中OO之静态关键字以及类常量的详解
2013/06/07 PHP
基于PHP CURL用法的深入分析
2013/06/09 PHP
php使用strtotime和date函数判断日期是否有效代码分享
2013/12/25 PHP
PHP基于redis计数器类定义与用法示例
2018/02/08 PHP
用jquery来定位
2007/02/20 Javascript
仅用[]()+!等符号就足以实现几乎任意Javascript代码
2010/03/01 Javascript
jQuery 操作option的实现代码
2011/03/03 Javascript
js数组的操作详解
2013/03/27 Javascript
js调用后台servlet方法实例
2013/06/09 Javascript
Javascript 函数parseInt()转换时出现bug问题
2014/05/20 Javascript
IE6 hack for js 集锦
2014/09/23 Javascript
解决jquery插件:TypeError:$.browser is undefined报错的方法
2015/11/21 Javascript
JS插件overlib用法实例详解
2015/12/26 Javascript
Node.js模块封装及使用方法
2016/03/06 Javascript
javascript原生ajax写法分享
2016/04/10 Javascript
理解AngularJs篇:30分钟快速掌握AngularJs
2016/12/23 Javascript
非常优秀的JS图片轮播插件Swiper的用法
2017/01/03 Javascript
webpack+vue中使用别名路径引用静态图片地址
2017/11/20 Javascript
vue实现a标签点击高亮方法
2018/03/17 Javascript
解决vue-cli脚手架打包后vendor文件过大的问题
2018/09/27 Javascript
React手稿之 React-Saga的详解
2018/11/12 Javascript
重学 JS:为啥 await 不能用在 forEach 中详解
2019/04/15 Javascript
微信小程序动态设置图片大小的方法
2019/11/21 Javascript
[03:52]显微镜下的DOTA2第三期——英雄在无聊的时候干什么
2014/06/20 DOTA
[03:06]V社市场总监Dota2项目负责人Erik专访:希望更多中国玩家加入DOTA2
2014/07/11 DOTA
Python爬虫中urllib库的进阶学习
2018/01/05 Python
通过python扫描二维码/条形码并打印数据
2019/11/14 Python
Pycharm2020最新激活码|永久激活(附最新激活码和插件的详细教程)
2020/09/29 Python
美国男士内衣品牌:Tommy John
2017/12/22 全球购物
龟牌英国商店:Turtle Wax Brand Store UK
2019/07/02 全球购物
银行柜员应聘推荐信范文
2013/11/24 职场文书
土木工程专业本科生求职信
2014/10/01 职场文书
打架赔偿协议书范本
2014/10/26 职场文书
月考总结与反思
2015/10/22 职场文书