zoukankan      html  css  js  c++  java
  • 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。

  • 相关阅读:
    java实现远程开机
    windows系统设备管理器显示全部硬件
    使用pl/sql在oracle中新建表和对应序列
    mysql,oracle,sql server中的默认事务隔离级别查看,更改
    没有外网情况下linux安装mysql
    解决IntelliJ IDEA 创建Maven项目速度慢问题 DarchetypeCatalog
    vmware中linux虚拟机使用NAT模式不能连接外网解决
    idea中新建的web项目不能新建servlet
    SSH开源框架的优缺点
    配置JDK环境变量,与各步骤的意义
  • 原文地址:https://www.cnblogs.com/kuaizifeng/p/9082794.html
Copyright © 2011-2022 走看看