前言:
现时兄弟们对“pythonwithopen函数”大体比较关注,兄弟们都想要剖析一些“pythonwithopen函数”的相关文章。那么小编也在网摘上汇集了一些有关“pythonwithopen函数””的相关内容,希望姐妹们能喜欢,咱们一起来了解一下吧!人是随着时间不断进化而来的,同样编程语言也是随着IT行业的更新换代,功能模块不断地优化与丰富才壮大起来的。比如在python2.5之前使用open读写文件操作就要注意。比如Python 程序打开一个文件后,往文件中写内容,写完之后,就要关闭该文件,否则会出现什么情况呢?极端情况下会出现 "Too many open files" 的错误,因为系统允许你打开的最大文件数量是有限的,默认打开文件最大文件数1024。
所以实际开发中要对可能发生异常的代码处进行 try 捕获,使用 try/finally 语句,因为如果在 try 代码块中程序出现了异常,后续代码就不再执行,而直接跳转到 except 代码块,但finally 块的代码无路如何最终都会被执行。因此,只要把 close 放在 finally 代码中,文件就一定会关闭,解决了这种隐藏的问题。
1.使用open读写文件,try捕捉异常处理,finally关闭文件
def f1(): 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关键字进行文件操作
def m2(): 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 [as variable]: with-block----------------------------------------------------------------------------案例1: with open("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()函数的功能class MyOpen(object): 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()#下面使用自定义的上下文管理器,#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@contextmanagerdef 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 装饰器,更进一步简化上下管理器的实现方式。但是实际开中,一般不需要不要开发者掌握with的实现原理,会使用即可哈。
标签: #pythonwithopen函数