• 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())
    
    
  • 相关阅读:
    Leetcode(337)-打家劫舍III
    Leetcode(213)-打家劫舍II
    Leetcode(198)-打家劫舍
    Leetcode(32)-最长有效括号
    计数排序
    智能指针
    C++中的explicit
    Leetcode(878)-第 N 个神奇数字
    Leetcode(877)-石子游戏
    C++的memset
  • 原文地址:https://www.cnblogs.com/dbf-/p/11840600.html
Copyright © 2020-2023  润新知