python上下文管理

上下文管理

位于 with 语句后的对象,with语句会对该对象进行上下文管理,即在进入with语句块前和退出语句块时会对该对象进行一些操作,这个操作分别在__enter__(self) 和 __exit__(self)中定义。

上下文管理原理

所谓的上下文管理是对一个对象而言,可以对对象使用with语句,定义一些进入操作和退出操作,这样即使在with语句块中出现了错误或者程序退出,仍然会执行我们定义的退出操作,通常我们使用结束操作执行一些释放资源的操作,保证在出错的情况下仍然会执行。

class Point:
    def __enter__(self):
        print("enter with") 
        return self
                  
    def __exit__(self):
        print("exit with")

p = P()

with p as s:    # 调用p.__enter__() ,s为__enter__的返回值
  pass

with Point():    # 同理
  pass

exit方法的参数和返回值

__exit__是with语句退出时执行的方法,如果这个语句块是因为出现错误退出的,__exit__函数是可以将其捕获的,并提供了三个参数方便对这个类型进行处理。如果没有错误,三个参数都为None

def __exit__(self, exc_type, exc_value, exc_tb):
# exc_type: 错误的类型
# exc_type:错误的值,定义错误时输入的指针
# exc_tb  :错误的traceback信息
    return  #return值为ture或者false决定了这个错误会不会压制,为True会压制错误

上下文管理工具contextlib.contextmanager

它是一个装饰器实现的上下文管理工具,装饰一个函数(这个函数必须是生成器函数),不用向类一样实现 enter 和 exit 方法,简便了操作

import contextlib
@contextlib.contextmanager
def foo():
    print("enter -----")    # 进入with时执行。
    yield 100               # with的返回值 
    print("")               # 退出with时候执行
    
with foo() as f:
    # process   #  进入和退出时候foo 函数执行

上面的函数无法解决 with 语句块中出现异常的情况。需要进一步改进,在函数中使用 try 捕异常,finally 保证 退出语句的正常执行。

@contextlib.contextmanager
def foo():
    print("enter -----")        # 进入with时执行。
    try:
        yield 100               # with的返回值 
    finally:
        print("exit-----")      # 退出with时候执行

with foo() as f:
    # process   

 

posted @ 2020-06-08 22:31  没有想象力  阅读(91)  评论(0编辑  收藏  举报