python上下方向键(Python:with的使用与上下文管理器)python初学 / python上下文管理器与with语句...

wufei123 发布于 2024-05-15 阅读(33)

人是随着时间不断进化而来的,同样编程语言也是随着IT行业的更新换代,功能模块不断地优化与丰富才壮大起来的比如在python2.5之前使用open读写文件操作就要注意比如Python 程序打开一个文件后,往文件中写内容,写完之后,就要关闭该文件,否则会出现什么情况呢?极端情况下会出现 "Too many open files" 的错误,因为系统允许你打开的最大文件数量是有限的,默认打开文件最大文件数1024。

所以实际开发中要对可能发生异常的代码处进行 try 捕获,使用 try/finally 语句,因为如果在 try 代码块中程序出现了异常,后续代码就不再执行,而直接跳转到 except 代码块,但finally 块的代码无路如何最终都会被执行。

因此,只要把 close 放在 finally 代码中,文件就一定会关闭,解决了这种隐藏的问题1.使用open读写文件,try捕捉异常处理,finally关闭文件deff1(): f = open(

"aaa.txt", "w+") try: f.write("hello ,world") except IOError: print("io 异常了啦"

) finally: f.close() f1() 复制代码使用上面处理当然没有任何问题,但在python2.5以后,基于之前的try....except....finally增加了一个功能更加简洁的方式with关键字。

with语句相对try/finally来说简洁了很多,而且也不需要每一个用户都去写f.close()来关闭文件了

2.使用with关键字进行文件操作defm2():with open("aaaa.txt","w+") as f : #open 方法的返回值给变量f,所以这里f可以自定义名称 f.write(

"hahhahaha") m2() 复制代码open 方法的返回值赋值给变量 f,这里f只是变量名,指向open返回值的引用当离开 with 代码块的时候,系统会自动调用 f.close() 方法, with 的作用和使用 try/finally 语句是一样的,所以这里不用手动写close()了。

上面那么为什么with可以实现这么强大的功能呢,即替代了try...finally,不用捕捉异常了,也不用手动调用close了,要想弄明白这个问题,先了解下python中的上下文管理器(Context Manager)。

3.什么是上下文管理器查看官网看是说:任何实现(重写)了 __enter__() 和 __exit__() 方法的对象都可称之为上下文管理器,搞不清context manager,内容管理器,为啥翻译成上下文管理器。

使用pycharm可以查看原来__enter__() 和 __exit__()是object类中自带的魔法方法****细心的人用ctrl键打开查看该方法的源码,发现打开不了,这是为啥子呢?因为python的解释器底层是用c语言写的(也有用java的)。

所以底层很多方法,都是查看不了源码的要想查看源码可以到github上搜搜但是一些导入的python库,用python实现的,是可以直接查看源码的所谓的上下文管理器其实是一个遵守了context management protocol 协议的对象。

就是一个对象,一个重写了object类中__enter__() 和 __exit__() 方法的对象这样的对象被称为上下文管理器Content Manager,它可以使用with关键字进行操作这个对象3.1 with语句使用的格式

with expression [asvariable]: with-block----------------------------------------------------------------------------

案例1: withopen("aaaa.txt","w+") as f : #open方法的返回值给变量f,相当于起个别名 f.write("hahhahaha") 复制代码这里expression是一个表达式,该表达式的结果必须是一个支持上下文管理协议的对象(即具有__enter__()和__exit__()方法的对象),比如案例中操作文件就是用的open("aaaa.txt","w+"),这个表达式返回的结果就是file对象。

具体返回的结果根据打开模式不同,返回值也不同,比如当open()用于以文本模式(w)打开文件时,它返回一个TextIOWrapper那么这么说,既然open()可以用with进行操作,底层必然实现了上下文管理器协议的。

查看官网可知一些标准Python对象现在都支持上下文管理协议,并且可以与with语句一起使用文件对象就是一个例子既然支持上下文管理协议,也就是实现底层实现了 __enter__()和__exit__()方法。

对象的__enter__()方法在with-block执行之前被调用,因此可以在类重写的__enter__方法里根据实际需求添加特定条件的过滤代码,__enter__方法具体使用后面再说在with-block 块的执行完成后,会调用对象的_exit__()方法,即使with-block块执行中引发异常,也可以运行这个__exit__方法,执行一些特定的操作(类似于try finally,finally无论是否有异常,都会执行其中的代码)。

比如文件对象就在这个__exit__方法里调用了close()函数,这样不管open操作是否异常,文件最终都会关闭3.2自定义一个实现了上下文管理器协议的对象:上下文管理器根据官网定义很简单,只要该类重写了object类中__enter__()和__exit__()方法即可。

#自定义一个上下文管理器,实现原open()函数的功能classMyOpen(object):def__init__(self, filename, mode): self.filename = filename

self.mode = mode def__enter__(self): print("entering") self.f = open(self.filename,

self.mode) returnself.f def__exit__(self, *args): print("will exit") self

.f.close() #下面使用自定义的上下文管理器,#1.首先MyOpen("bbbb.txt","w") 先执行__init__,完成初始化,返回的是一个支持上下文管理器协议的对象给f#2.然后执行__enter__函数,该函数执行open()方法操作文件,并且返回这个file对象。

#3.根据返回的file对象f,这个时候执行f.f.write("hello ,hahahhah")#4.不管第三步是否异常,最后都会调用__exit__执行文件的close. with MyOpen(

"bbbb.txt","w") as f: f.write("hello ,hahahhah") 复制代码4.实现上线文管理器的其他方式Python 还提供了一个 contextmanager 的装饰器,更进一步简化了上下文管理器的实现方式。

通过 yield 将函数分割成两部分,yield 之前的语句在 __enter__ 方法中执行,yield 之后的语句在 __exit__ 方法中执行紧跟在 yield 后面的值是函数的返回值具体详细参考python官网:。

docs.python.org/release/2.6…from contextlib import contextmanager @contextmanagerdefmy_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 装饰器,更进一步简化上下管理器的实现方式但是实际开中,一般不需要不要开发者掌握with的实现原理,会使用即可哈

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

河南中青旅行社综合资讯 奇遇综合资讯 盛世蓟州综合资讯 综合资讯 游戏百科综合资讯 新闻38240