Python上下文管理器

  注意一下代码:

  

def try_method():
    try:
        print('code started')
        raise KeyError
        return 1

    except KeyError as e:
        print('keyerror')
        return 2

    finally:
        print('finally')
        return 4

s = try_method()
print(s)
输出结果:
code started
keyerror
finally
4

关于最后结果为什不是2?

  在except语句中是捕捉到了KeyError错误。return2,此时会将结果2压入到栈中,然后会继续执行finally语句,finally语句return4后继续压入到栈中,然后s的值为从栈中取出

的值,即为4而不是2,如果finally最后没有reuturn结果,那么s的值就为2。

  要使得自己定义的类满足上下文管理器协议,类中必须定义一下连个魔法方法:

1:__enter__()

2:__exit__()

例:

class Sample():
    def __enter__(self):
        print('Enter')
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('Exit')

    def do_something(self):
        print('doing something')
with Sample() as s:
    s.do_something()
输出结果:
Enter
doing something
Exit

  用with调用类开始调用的时候,会执行__enter__()方法,调用完成退出的时候一定会执行类中的__exit__()方法。于是最后悔打印出Exit。利用此可以在__enter__()方法中获取资源, 然后再__exit__()中释放资源。

更加简单的方式用contextlib:

import contextlib
@contextlib.contextmanager
def open(file_name):
    print('file wil be opened')
    yield 'something'
    print('file ended')
with open('**.txt') as f:
    print('file processing')
输出结果:
file wil be opened
file processing
file ended

 在yield语句之前语句就相当于__enter__()内的语句。yield之后的语句相当于__exit__()内的语句。因此都会会执行file ended。

原文地址:https://www.cnblogs.com/yc3110/p/10447255.html