Python with

Python with

with 语句用于包装带有使用上下文管理器定义的方法的代码块的执行
可以用来替代 try 语句

执行过程

  1. 对上下文表达式求值,获得一个上下文管理器
  2. 载入上下文管理器的 __exit__()
  3. 发起调用上下文管理器的 __enter__() 方法
  4. 如果 with 语句包含一个目标,来自 __enter__() 的返回值将被赋予它
  5. 执行语句
  6. 调用 __exit__(),如果执行语句时出现异常:将异常的类型、值、回溯信息传给 __exit__();如果没有异常:传入 None

替代 try 语句

以打开文件为例:
try 语句:

f = open("text.txt", "r")
    try:
        print(f.read())
    except Exception:
        print("error occurred")
    finally:
        f.close()

with 语句:

with open("text.txt", "r") as f:
	print(f.read())

上下文管理器 (context managers)

上下文管理器属于上下文管理器类型 (Context Manager Types),用于 with 语句定义运行上下文
__enter__()__exit__() 的对象都可以是上下文管理器

方法

contextmanager.__enter__()

with open() as f: 为例:文件对象会从 __enter__() 返回自身,使得 open() 可以被用作上下文表达式 (context expression)

contextmanager.__exit__(exc_type, exc_val, exc_tb)

返回 True 时表示屏蔽异常,会继续执行 with 之后的语句;返回 False 时异常会在此方法执行结束后继续传播

自定义上下文管理器

实现打开文件的功能:

class UserContextManager(object):
    def __init__(self, file_name, mode):
        self.file_name = file_name
        self.mode = mode

    def __enter__(self):
        self.f = open(self.file_name, self.mode)
        return self.f

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.f.close()


with UserContextManager("text.txt", "r") as f:
    print(f.read())

contextlib

Python 标准库中的 contextlib 包含许多支持 with 语句的程序
官方文档:https://docs.python.org/zh-cn/3/library/contextlib.html#module-contextlib

contextmanager

contextmanager 可以通过一个装饰器,实现 with 语句的功能
yield 之前的语句在 __enter__() 中执行,yield 之后的语句在 __exit__() 中执行,yield 的为 __enter__() 的返回值

from contextlib import contextmanager


@contextmanager
def user_open(path, mode):
    f = open(path, mode)
    yield f
    f.close()


with user_open('text.txt', 'r') as f:
    print(f.read())

posted on 2019-11-12 11:16  doubtful  阅读(202)  评论(0编辑  收藏  举报

导航