Python33_上下文管理器

2019-09-27  本文已影响0人  jxvl假装

上下文管理器

  1. __enter__进入的方法,负责一些更改
  2. __exit__退出方法,将进入时所做的更改还原

import sys


class LookingGlass:
    def __init__(self, *args):
        pass
        
    def __enter__(self):
        import sys
        self.original_write = sys.stdout.write  #系统的输入函数,输出到控制台
        sys.stdout.write = self.reverse_write
        return "Python is the best language"

    def reverse_write(self, text):
        self.original_write(text[::-1])

    def __exit__(self, exc_type, exc_val, exc_tb):
        """
        不管是否产生异常,exit一定会调用
        :param exc_type: 异常的类型
        :param exc_val: 异常的值,except ZeroDivisionError as data中的data就是异常的实例
        :param exc_tb: traceback对象,存储的是堆栈里面的错误信息
        :return:
        """
        sys.stdout.write = self.original_write
        return True #如果返回True则代表已经正确处理异常,如果返回True以外的其他值,则代表异常未处理,异常会层层上抛

with LookingGlass() as what:    #what存储了进入时返回的值。注意LookingGlass后面的括号
    # 对于上下文管理器,也可以对其像一个一般的类那样进行传参(如果init方法中定义了)
    print("hello world")    #逆序输出
    print(what) #这里会输出"Python is the best language"的逆序

print("hello world")    #因为已经退出了上下文环境,所以这里是正常输出

ps:用with打开文件即是一个上下文环境的运用。

注意:

  1. 以yield为分界点,之前相当于enter的东西,之后的相当于exit的东西
import contextlib   #简化上述过程的包

@contextlib.contextmanager
def looking_glass():    #注意这里的定义方式类似于函数,而并非上面的类
    import sys
    original_write = sys.stdout.write   #和之前enter所做的事情一样

    def reverse_write(text):
        original_write(text[::-1])  #实现逆序输出

    sys.stdout.write = reverse_write    
    try:
        yield "Python is the best language" #以yield为分界点,之后的相当于__exit__中的代码,
        # yield的值相当于__enter__中的返回值,yield之前的代码相当于__enter__中的代码
    except Exception:
        print("处理异常...")
    sys.stdout.write = original_write

with looking_glass() as what:
    print("ABCDFG")
    print(what)

eg:对于套接字(网络编程部分)、文件描述符等珍贵的资源,可以结合上下文管理器进行释放或关闭等

上一篇下一篇

猜你喜欢

热点阅读