python的上下文管理器-1
reference:https://zhuanlan.zhihu.com/p/26487659
来看看如何正确关闭一个文件。
普通版:
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 语句了。
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 #这个返回值赋值给了as 后面的变量f
def __exit__(self, *args):
print("will exit")
self.f.close()
with File('out.txt', 'w') as f:
print("writing")
f.write('hello, python')
'''
执行结果:
entering
writing
will exit
'''
这样,你就无需显示地调用 close 方法了,由系统自动去调用,哪怕中间遇到异常 close 方法也会被调用。
python的上下文管理器-1的更多相关文章
- 谈一谈Python的上下文管理器
		
经常在Python代码中看到with语句,仔细分析下,会发现这个with语句功能好强,可以自动关闭资源.这个在Python中叫上下文管理器Context Manager.那我们要怎么用它,什么时候用它 ...
 - python contextlib 上下文管理器
		
1.with操作符 在python中读写文件,可能需要这样的代码 try-finally读写文件 file_text = None try: file_text = open('./text', 'r ...
 - python使用上下文管理器实现sqlite3事务机制
		
如题,本文记录如何使用python上下文管理器的方式管理sqlite3的句柄创建和释放以及事务机制. 1.python上下文管理(with) python上下文管理(context),解决的是这样一类 ...
 - 【Python】 上下文管理器和contextlib
		
上下文管理器 一直对python中的上下文管理比较迷惑,趁着今天研究SQLAlchemy顺便看了一下,感觉稍微清楚了一点.http://www.cnblogs.com/chenny7/p/421344 ...
 - python 黑魔法 ---上下文管理器(contextor)
		
所谓上下文 计算机上下文(Context)对于我而言,一直是一个很抽象的名词.就像形而上一样,经常听见有人说,但是无法和现实认知世界相结合. 最直观的上下文,莫过于小学的语文课,经常会问联系上下文,推 ...
 - Python 的上下文管理器是怎么设计的?
		
花下猫语:最近,我在看 Python 3.10 版本的更新内容时,发现有一个关于上下文管理器的小更新,然后,突然发现上下文管理器的设计 PEP 竟然还没人翻译过!于是,我断断续续花了两周时间,终于把这 ...
 - python的上下文管理器
		
直接上代码: f = open('123.txt','w') try: f.write('hello world') except Exception: pass finally: f.close() ...
 - 【Python】【上下文管理器】
		
"""#[备注]#1⃣️try :仅当try块中没有异常抛出时才运行else块.#2⃣️for:仅当for循环运行完毕(即for循环没有被break语句终止)才运行els ...
 - python2.7高级编程  笔记一(Python中的with语句与上下文管理器学习总结)
		
0.关于上下文管理器上下文管理器是可以在with语句中使用,拥有__enter__和__exit__方法的对象. with manager as var: do_something(var) 相当于以 ...
 
随机推荐
- 手动脱Mole Box壳实战总结
			
作者:Fly2015 这个程序是吾爱破解脱壳练习第8期的加壳程序,该程序的壳是MoleBox V2.6.5壳,这些都是广告,能够直接无视了.前面的博客手动脱Mole Box V2.6.5壳实战中已经给 ...
 - STL之pair类型具体分析
			
pair定义于头文件utility中.基本的作用是将两个数据组合成一个数据,两个数据能够是同一类型或者不同类型. pair类型提供的操作: pair<T1,T2> p1; pair< ...
 - spring(16)------spring的数据源配置
			
在spring中,通过XML的形式实现数据源的注入有三种形式. 一.使用spring自带的DriverManagerDataSource 使用DriverManagerDataSource配置数据源与 ...
 - UIView创建的两种方式
			
//通过xib创建 NSBundle * bundle = [NSBundle mainBundle]; NSArray * arr = [bundle loadNibNamed:@"myV ...
 - .NET实现爬虫
			
前几天看到一个.NET Core写成的爬虫,有些莫名的小兴奋,之前一直用集搜客去爬拉勾网的招聘信息,这个傻瓜化工具相当于用HTML模板页去标记DOM节点,然后在浏览器窗口上模拟人的浏览行为同时跟踪节点 ...
 - dede二级导航与二级栏目 ----内容介绍二级导航
			
{dede:channelartlist typeid='top'}//如果只需要拿一列,则需要使用row='1'这个属性否则会根据子频道的数目循环输出 <a href="{dede: ...
 - Linux相互排斥与同步应用(三):posix线程实现单个生产者和单个消费者模型
			
[版权声明:尊重原创.转载请保留出处:blog.csdn.net/shallnet 或 .../gentleliu.文章仅供学习交流,请勿用于商业用途] 在第一节说到了 ...
 - Redis专题(2):Redis数据结构底层探秘
			
前言 上篇文章Redis闲谈(1):构建知识图谱介绍了redis的基本概念.优缺点以及它的内存淘汰机制,相信大家对redis有了初步的认识.互联网的很多应用场景都有着Redis的身影,它能做的事情远远 ...
 - apt-mirror 校验错误文件处理
			
apt-mirror是一个用来将Debian或Ubuntu的软件源镜像到本地的工具,这个工具工作得非常好,不过有的时候由于网络问题,会有一些文件的校验是失败的,但apt-mirror并不能发现,等到最 ...
 - vs中使用M_PI的问题及解决  角度转弧度&根据弧度计算圆周上点的坐标的方法
			
M_PI 是一个宏定义,圆周率的定义 C/C++ code #define M_PI 3.14159265358979323846 此宏定义和编译器有关,TC中M_PI宏就定义在& ...