python文件之上下文管理语句with,python中的上下文管理器
仅供学习,转载请注明出处。
有了“上下文管理器”如果你有阅读源代码的习惯,你可能会看到一些优秀的代码,它们经常有带“With”关键字的语句。一般用在什么场景?
对于系统资源,如文件、数据库连接和套接字,应用程序在打开这些资源并执行业务逻辑后必须做的一件事是关闭(断开)资源。
比如Python程序打开一个文件,把内容写到文件里,写完之后会把文件关闭。否则会怎么样?在极端情况下,会出现“打开的文件太多”的错误,因为系统允许打开的最大文件数是有限的。
同样,对于数据库来说,如果连接太多,又没有及时关闭,可能会出现‘无法连接MySQL服务器连接太多’的情况,因为数据库连接是一个非常昂贵的资源,不能无限创建。
让我们看看如何正确关闭文件。
普通版本:def file1():
f=open(fatboss.txt , w )
f .写(“胖老板:年轻人,买包槟榔”)
f.close()
if __name__==__main__ :
1 file1()执行如下:
[root@server01 with]# ls
test1.py
[root@server01 with]#
[root @ server 01 with]# python 3 test1 . py
[root@server01 with]#
[root@server01 with]# ls
fatboss.txt test1.py
[root @ server 01 with]# cat fat boss . txt
老板:小伙子买包槟榔[root@server01 with]#
[root@server01 with]#这个方法比较繁琐,就是文件写完之后,手动关闭。但是如果写过程异常,会报错,终止整个python进程。
那么,为了解决这个异常的问题,我们可以增加尝试捕获异常的机制。
捕获到异常版本定义文件1():
尝试:
f=open(fatboss.txt , w )
除了IOError:
打印(打开文件时出现异常!)
否则:
F.write(胖老板:买包芙蓉王,小伙子)
最后:
f.close()
if __name__==__main__ :
文件1()
程序使用try/finally语句捕获可能发生异常的代码,这意味着如果程序在try代码块中出现异常,那么后续代码将不再执行,而是直接跳转到except代码块。如果没有异常,跳转到else代码块执行。无论如何,finally块的代码最终都会被执行。因此,只要在finally代码中加上close,文件就会被关闭。
按如下方式运行:
[root @ server 01 with]# python 3 test1 . py
[root @ server 01 with]# cat fat boss . txt
老板:小伙子买包芙蓉王[root@server01 with]#
[root@server01 with]#但是如果这样写,代码就要写很多了。有没有简单的方法?
下面介绍一下with关键字的用法。
With缩写为def file1():
用open(fatboss.txt , w )作为f:
F.write(“胖老板:年轻人,买包兰利群”)
if __name__==__main__ :
1 file1()运行如下:
[root @ server 01 with]# python 3 test1 . py
[root@server01 with]#
[root @ server 01 with]# cat fat boss . txt
老板:小伙子,买包兰利群吧。将[root@server01 with]#with关键字后open方法的返回值赋给变量f,当离开with代码块时,系统会自动调用f.close()方法。with的功能与使用try/finally语句相同。那么它的实现原理是什么呢?在讲with的原理之前,还要涉及到另一个概念,那就是上下文管理器。
语境是什么?语境在不同的地方有不同的意思,要懂事。
比如胖老板一开口就拦住了我,所以就是上面这个。
下一步是什么?
当然是买烟可乐槟榔啦!这是下面的。
哦,那是上下文?
咄
上下文管理器任何实现__enter__()和__exit__()方法的对象都可以称为上下文管理器,并且上下文管理器对象可以使用with关键字。显然,file对象也实现了上下文管理器。
那么文件对象是如何实现这两种方法的呢?我们可以自己模拟实现一个文件类,让类实现__enter__()和__exit__()方法。
类文件():
def __init__(自身,文件名,模式):
self.filename=文件名
self.mode=模式
def __enter__(自身):
打印(“输入”)
self.f=open(self.filename,self.mode)
回归自我
def __exit__(self,*args):
打印(“退出”)
self.f.close()
def main():
#使用自定义文件类来实现。
用File(fatboss2.txt , w )作为f:
f .写(‘胖老板:一套槟榔和芙蓉!’)
if __name__==__main__ :
Main()运行如下:
[root @ server 01 with]# python 3 test2 . py
进入
退出
[root@server01 with]# ls
fat boss 2 . txt fat boss . txt test1 . py test2 . py
[root@server01 with]# cat fatboss
猫:胖老板:没有这样的文件或目录
[root @ server 01 with]# cat fat boss 2 . txt
老板:槟榔芙蓉一套![root@server01 with]#
[root@server01 with]# __enter__()方法返回资源对象,这里是你将要打开的文件对象,而__exit__()方法处理一些清理工作。
因为File类实现了上下文管理器,所以现在可以使用with语句。
用@contextmanager Python实现contextmanager的另一种方法也为上下文管理器提供了一个装饰器,这进一步简化了上下文管理器的实现。
该功能按产量分为两部分。yield之前的语句在__enter__方法中执行,yield之后的语句在__exit__方法中执行。紧随yield之后的值是函数的返回值。
从上下文库导入上下文管理器
@上下文管理器
def my_open(路径,模式):
f=打开(路径,模式)# __回车_ _
产量f
f.close() ## __exit__
def main():
#使用自定义文件类来实现。
用my_open(fatboss2.txt , w )作为f:
f .写(‘胖老板:一套槟榔、芙蓉和兰利群!\n )
if __name__==__main__ :
Main()运行如下:
[root @ server 01 with]# python 3 test2 . py
[root@server01 with]#
[root @ server 01 with]# cat fat boss 2 . txt
老板:一套槟榔、芙蓉和兰利群!
[root@server01 with]#摘要
Python提供了with语法来简化资源操作的后续清除操作,这是try/finally的替代方法。其实现原理是基于上下文管理器。此外,Python还提供了一个contextmanager装饰器,进一步简化了上层和下层管理器的实现。
关注微信微信官方账号,回复【数据】,Python,PHP,JAVA,web,即可获取Python,PHP,JAVA,前端等视频数据。
来自海洋的渔夫原创作品,
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。