• python模块之contexlib


    一、上下文管理器

      with是python实现上下文管理器的核心关键词。它能够在代码执行前和执行后做一些额外的事情。

      最常见的代码恐怕就是文件操作了。

    with open("file", "r", encoding="utf-8") as f:
        data = f.read()
    import functools
    reader = functools.partial(open, mode="r", encoding="utf-8")
    f = reader("homework/user.txt")
    f.readlines()

      实际上,with语句是通过__enter__和__exit__来实现的。

    class Open(object):
        def __init__(self, file, mode, encoding="GBK"):
            """初始化,生成文件句柄"""
            self.file = file
            self.mode = mode
            self.encoding = encoding
        
        def __enter__(self):
            print("__enter__ has called.")
            try:
                f = open(self.file, self.mode, self.encoding)
                return f
            except Exception as e:
                print(e)
                
        def __exit__(self, exc_type, exc_val, exc_tb):
            print("__exit__ has called.")
            print("exc_type: ", exc_type)
            print("exc_val: ", exc_val)
            print("exc_tb: ", exc_tb)
    
    with Open("有关协议.docx", mode='r', encoding="GBK") as f:
        data = f.readlines()
    
    """
    __enter__ has called.
    an integer is required (got type str) # 异常提示信息
    __exit__ has called.
    exc_type:  <class 'AttributeError'>
    exc_val:  'NoneType' object has no attribute 'readlines'
    exc_tb:  <traceback object at 0x110ade608>
    """

      with在开始时调用__enter__,并将结果赋给as后面的变量f。在结束时会调用__exit__,如果有异常,则会把异常类型、异常值和跟踪地址作为参数传递给__eixt__。

      如果我们自己使用with,则必须在定义的类中实现__enter__和__exit__方法。

    二、contextlib模块

      python3内置了contextlib模块来帮助我们更加方便地实现上下文管理器。

    import contextlib
    @contextlib.contextmanager
    def file_open(file_name, mode="r", encoding="utf-8"):
        print("file open")
        yield open(file_name, mode=mode, encoding=encoding)
        print("file end")
    
    with file_open("log.txt") as f:
        print("Read file.")
        print(f)
        dic = f.read()
        print(dic)

      contextlib必须调用装饰器来装饰一个需要使用with语句的函数。在函数内部必须要使用yield将该函数变成可迭代对象。

      在with时,将yield返回值赋给as后的变量。此时已执行到yield时。f包裹的内容作为do something继续执行。最后才会执行file end。

  • 相关阅读:
    jsp转向
    什么是 XDoclet?
    tomcat中的几点配置说明
    mysql5问题
    POJ 3734 Blocks
    POJ 2409 Let it Bead
    HDU 1171 Big Event in HDU
    POJ 3046 Ant Counting
    HDU 2082 找单词
    POJ 1286 Necklace of Beads
  • 原文地址:https://www.cnblogs.com/kuaizifeng/p/9082794.html
Copyright © 2020-2023  润新知