Python之 context manager

在context manager中,必须要介绍两个概念:
with as... , 和 enterexit.
下文将先介绍with语句,然后介绍 enter__和__exit, 最后介绍context manager.

  • with语句的作用
    它的好处是自动运行try finally语句,从而不需要人工去处理异常。

示例:

with open('some_file', 'w') as  opened_file:
    opened_file.write('Hola!')

等同于:

file = open('some_file', 'w')
try:
    file.write('Hola!')
finally:
    file.close()

首先我们自己实现一个一般情况下的context manager。

class File(object):
    def __init__(self, file_name, method):
        self.file_obj = open(file_name, method)
    def __enter__(self):
        return self.file_obj
    def __exit__(self, exc_type, exc_value, traceback):
        # 三个参数是在运行过程中能引起异常的情况。 当context能够正常退出时,是哪个参数都为None.
        self.file_obj.close()
        

当运行with语句时

with File('demo.txt', 'w') as opened_file:
    opened_file.write('Hola!')

运行过程:
1、先运行 __init__ 生成文件句柄 opened_file
2. __enter__方法打开文件并且返回文件对象。
3. 将文件对象传递给句柄opened_file
4. 写文件调用.write()
5. with语句调用后__exit__,关闭这个文件。

tips:
可以补充代码在__enter____exit———— 中,这样在对文件操作的开始和退出时进行相应的动作。

另一种context manager的使用方式

使用contextlib模块。它将contextmanager当作decorator和generator使用。不需要自己构造类,写__enter____exit__函数。

示例代码:

from contextlib import contextmanager

@contextmanager
def open_file(name):
    f = open(name, 'w')
    yield f
    f.close()
    
with open_file('some_file') as f:
    f.write('hola!')

open_file()是一个generator,
同时他作为decorator-- contextmanager的参数。
当我们运行with语句时,contextmanager会自动运行__enter____exit__.
同时写入文件是通过genarator来实现的。

posted @ 2016-11-28 14:31  geek精神  阅读(538)  评论(0编辑  收藏  举报