专栏名称: Python开发者
人生苦短,我用 Python。伯乐在线旗下账号「Python开发者」分享 Python 相关的技术文章、工具资源、精选课程、热点资讯等。
目录
相关文章推荐
Python开发者  ·  程序员的“冰火两重天”:转型之路如何破局? ·  3 天前  
Python开发者  ·  matplotlib + ... ·  5 天前  
Python开发者  ·  突发!OpenAI 紧急上书,呼吁禁用 ... ·  4 天前  
Python爱好者社区  ·  75k,直接封神! ·  2 天前  
Python爱好者社区  ·  董事长。。。刺死。。。技术总监。。。已被捕。。。 ·  4 天前  
51好读  ›  专栏  ›  Python开发者

谈一谈 Python 的上下文管理器

Python开发者  · 公众号  · Python  · 2016-12-30 20:21

正文

(点击 上方公众号 ,可快速关注)


来源:思诚之道

链接:www.bjhee.com/python-context.html

如有好文章投稿,请点击 → 这里了解详情


经常在Python代码中看到with语句,仔细分析下,会发现这个with语句功能好强,可以自动关闭资源。这个在Python中叫上下文管理器Context Manager。那我们要怎么用它,什么时候用它呢。这里我们就来聊一聊。


上下文管理器的作用


很多情况,当我们使用完一个资源后,我们需要手动的关闭掉它,比如操作文件,建立数据库连接等。但是,在使用资源的过程中,如果遇到异常,很可能错误被直接抛出,导致来不及关闭资源。所以在大部分程序语言里,我们使用”try-finally”语句来确保资源会关闭。比如下面的Python写文件代码:


try :

f = open ( 'test.txt' , 'a+' )

f . write ( 'Foo\n' )

finally :

f . close ()


这样做固然没有问题,但是当”try-finally”中间的逻辑复杂,而且还带有各种嵌套的话,代码就很不容易维护。Python的with语句,可以说功能同上面的”try-finally”几乎一样,但代码看上去简洁的多,我们来实现同样的功能:


with open ( 'test.txt' , 'a+' ) as f :

f . write ( 'Foo\n' )


with语句后面跟着open()方法,如果它有返回值的话,可以使用as语句将其赋值给f。在with语句块退出时,”f.close()”方法会自动被调用,即使”f.write()”出现异常,也能确保close()方法被调用。


自定义类来使用上下文管理器


上例中”open()”方法是Python自带的,那我们怎么定义自己的类型来使用with语句呢。其实只要你的类定义了”__enter__()”和”__exit__()”方法,就可以使用Python的上下文管理器了。”__enter__()”方法会在with语句进入时被调用,其返回值会赋给as关键字后的变量;而”__exit__()”方法会在with语句块退出后自动被调用。


我们来实现个跟上节一样的文件写入功能:


class OpenFileDemo ( object ) :

def __init__ ( self , filename ) :

self . filename = filename

def __enter__ ( self ) :

self . f = open ( self . filename , 'a+' )

return self . f

def __exit__ ( self , exc_type , exc_val , exc_tb ) :

self . f . close ()

with OpenFileDemo ( 'test.txt' ) as f :

f . write ( 'Foo\n' )


异常处理


肯定有朋友注意到上面的”__exit__()”带了三个参数,是的,他们是用来异常处理的。大部分情况下,我们希望with语句中遇到的异常最后被抛出,但也有时候,我们想处理这些异常。”__exit__()”方法中的三个参数exc_type, exc_val, exc_tb分别代表异常类型,异常值,和异常的Traceback。当你处理完异常后,你可以让”__exit__()”方法返回True,此时该异常就会不会再被抛出。比如我们将上例中的”__exit__()”方法改一下:


def __exit__ ( self , exc_type , exc_val , exc_tb ) :

self . f . close ()

if







请到「今天看啥」查看全文