正确理解python中的关键字“with”与上下文管理器

来源:中文源码网    浏览: 次    日期:2018年9月2日

【下载文档:  正确理解python中的关键字“with”与上下文管理器.txt 】

(友情提示:右键点上行txt文档名->目标另存为)

正确理解python中的关键字“with”与上下文管理器 前言

如果你有阅读源码的习惯,可能会看到一些优秀的代码经常出现带有 “with” 关键字的语句,它通常用在什么场景呢?今天就来说说 with 和 上下文管理器。

对于系统资源如文件、数据库连接、socket 而言,应用程序打开这些资源并执行完业务逻辑之后,必须做的一件事就是要关闭(断开)该资源。

比如 Python 程序打开一个文件,往文件中写内容,写完之后,就要关闭该文件,否则会出现什么情况呢?极端情况下会出现 "Too many open files" 的错误,因为系统允许你打开的最大文件数量是有限的。

同样,对于数据库,如果连接数过多而没有及时关闭的话,就可能会出现 "Can not connect to MySQL server Too many connections",因为数据库连接是一种非常昂贵的资源,不可能无限制的被创建。

来看看如何正确关闭一个文件。

普通版:

def m1():

f = open("output.txt", "w")

f.write("python之禅")

f.close()这样写有一个潜在的问题,如果在调用 write 的过程中,出现了异常进而导致后续代码无法继续执行,close 方法无法被正常调用,因此资源就会一直被该程序占用者释放。那么该如何改进代码呢?

进阶版:

def m2():

f = open("output.txt", "w")

try:

f.write("python之禅")

except IOError:

print("oops error")

finally:

f.close()改良版本的程序是对可能发生异常的代码处进行 try 捕获,使用 try/finally 语句,该语句表示如果在 try 代码块中程序出现了异常,后续代码就不再执行,而直接跳转到 except 代码块。而无论如何,finally 块的代码最终都会被执行。因此,只要把 close 放在 finally 代码中,文件就一定会关闭。

高级版:

def m3():

with open("output.txt", "w") as f:

f.write("Python之禅")一种更加简洁、优雅的方式就是用 with 关键字。open 方法的返回值赋值给变量 f,当离开 with 代码块的时候,系统会自动调用 f.close() 方法, with 的作用和使用 try/finally 语句是一样的。那么它的实现原理是什么?

在讲 with 的原理前要涉及到另外一个概念,就是上下文管理器(Context Manager)。

上下文管理器

任何实现了 __enter__() 和 __exit__() 方法的对象都可称之为上下文管理器,上下文管理器对象可以使用 with 关键字。显然,文件(file)对象也实现了上下文管理器。

那么文件对象是如何实现这两个方法的呢?我们可以模拟实现一个自己的文件类,让该类实现 __enter__() 和 __exit__() 方法。

class File(): def __init__(self, filename, mode):

self.filename = filename

self.mode = mode def __enter__(self):

print("entering")

self.f = open(self.filename, self.mode)

return self.f def __exit__(self, *args):

print("will exit")

self.f.close()__enter__() 方法返回资源对象,这里就是你将要打开的那个文件对象, __exit__() 方法处理一些清除工作。

因为 File 类实现了上下文管理器,现在就可以使用 with 语句了。

with File('out.txt', 'w') as f:

print("writing")

f.write('hello, python')这样,你就无需显示地调用 close 方法了,由系统自动去调用,哪怕中间遇到异常 close 方法也会被调用。

contextlib

Python 还提供了一个 contextmanager 的装饰器,更进一步简化了上下文管理器的实现方式。通过 yield 将函数分割成两部分,yield 之前的语句在 __enter__ 方法中执行,yield 之后的语句在 __exit__ 方法中执行。紧跟在 yield 后面的值是函数的返回值。

from contextlib import contextmanager@contextmanager

def my_open(path, mode):

f = open(path, mode)

yield f

f.close()调用

with my_open('out.txt', 'w') as f:

f.write("hello , the simplest context manager")总结

Python 提供了 with 语法用于简化资源操作的后续清除操作,是 try/finally 的替代方法,实现原理建立在上下文管理器之上。此外,Python 还提供了一个 contextmanager 装饰器,更进一步简化上下管理器的实现方式。以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对中文源码网的支持。

亲,试试微信扫码分享本页! *^_^*

python的上下文管理用哪个关键字_正确理解python中的关键字“with”与上下文管理器...相关推荐

  1. python函数可以作为容器对象吗_正确理解Python函数是第一类对象

    正确理解 Python函数,能够帮助我们更好地理解 Python 装饰器.匿名函数(lambda).函数式编程等高阶技术. 函数(Function)作为程序语言中不可或缺的一部分,太稀松平常了.但函数 ...

  2. python with关键字_完全理解Python关键字with与上下文管理器

    如果你有阅读源码的习惯,可能会看到一些优秀的代码经常出现带有 "with" 关键字的语句,它通常用在什么场景呢?今天就来说说 with 和 上下文管理器. 对于系统资源如文件.数据 ...

  3. 用python画爱心再加一行文字_如何理解python一行代码实现一个爱心字符画?

    前言 python中有个很酷的效果,一行代码实现一个爱心字符,虽说是一行代码,但是理解起来还是比较难的,括号太多,并且使用了python的一些快捷小技巧.比如三元表达式,列表生成式,字符串拼接以及一个 ...

  4. mysql中having的意思_正确理解MySQL中的where和having的区别

    展开全部 1.where和having都可以使用的32313133353236313431303231363533e4b893e5b19e31333363383964场景select goods_pr ...

  5. 正确理解Python函数是第一类对象

    正确理解 Python函数,能够帮助我们更好地理解 Python 装饰器.匿名函数(lambda).函数式编程等高阶技术. 函数(Function)作为程序语言中不可或缺的一部分,太稀松平常了.但函数 ...

  6. python 释放变量所指向的内存_通俗易懂的Python垃圾回收机制及内存管理

    Python垃圾回收机制及内存管理 内存管理: 先定义一个变量 name='wxl' 那么python会在内存中开辟一小块区域存放"wxl",此时变量的值是我们真正想要存储的,wx ...

  7. python语句解释_深入理解python with 语句

    深入理解python with 语句 python中with 语句作为try/finally 编码范式的一种替代, 适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的" ...

  8. python n个list如何组成矩阵_学完Python,我决定熬夜整理这篇总结...

    来源:http://suo.im/5wzRqt 前言:学完Python,我决定熬夜整理这篇总结- 一.了解Python Python之父 Guido Van Rossum,一位荷兰程序员,在1989年 ...

  9. python ioc框架_轻松理解 Spring 中的 IOC

    Spring 简介 Spring 是一个开源的轻量级的企业级框架,其核心是反转控制 (IoC) 和面向切面 (AOP) 的容器框架.我们可以把 Spring 看成是对象的容器,容器中可以包含很多对象, ...

最新文章

  1. (续)我对09毕业生说两句
  2. iOS 苹果app提交 ITC.apps.validation.prerelease_build_missing
  3. SAP Spartacus 的页面布局
  4. Python要点总结,我使用了100个小例子!
  5. 异步fifo_FIFO工作的原理
  6. tomcat没有编译重新编写的代码
  7. React学习笔记 - 组件Props
  8. weak和assign的区别
  9. 7月25日训练赛签到题HDU1257
  10. python基础教学PPT讲义(基础部分)
  11. Hbase学习(四)---hbase 的下载,maven依赖,以及官网文档
  12. O2O C2C B2B B2C
  13. 计算机输入什么指令关机,电脑自动关机命令是什么
  14. fantastic-matplotlib:案例集合:
  15. 暗影精灵8 Pro 安装 Ubuntu20.04 问题记录
  16. 计算机知识与技能竞赛配图,第七届”高教杯“全国大学生先进成图技术与产品信息建模创新大赛机械类计算机绘图试卷.doc...
  17. 基于PANDA做DTI分析
  18. NXP i.MX6Q 双屏同显hdmi显示闪烁解决方案
  19. Struts原理与实践
  20. CVE-2022-1162 Gitlab 硬编码漏洞分析

热门文章

  1. PELU激活函数的tensorflow实现(一) Parametric Exponential Linear Unit
  2. 软件需求工程--需求分析
  3. linux摄像头拍照程序,Android开发:Camera初探——控制摄像头拍照
  4. K8S(一)VMware Fusion 构建基本k8s集群
  5. (LeetCode)Java 求解正则表达式匹配
  6. tensorflow slim 安装教程
  7. php 搜索字符串ctrl f_js搜索关键字(Ctrl + F)
  8. 关于谷歌眼镜的几点常见问题
  9. 使用 Docker 安装 Zabbix,并配置自定义监控项
  10. 求通俗解释下bandit老虎机是个什么东西?