美文网首页
上下文管理器

上下文管理器

作者: 云深沧海暮 | 来源:发表于2021-02-26 13:40 被阅读0次

前言

在阅读yolov5源码时,发现管理进程间数据同步的torch_distributed_zero_first函数用到了上下文管理器,现记录下关于contextmanager和yield结合时的运行逻辑。

@contextmanager
def torch_distributed_zero_first(local_rank: int):
    """
    Decorator to make all processes in distributed training wait for each local_master to do something.
    """
    if local_rank not in [-1, 0]:
        torch.distributed.barrier()
    yield
    if local_rank == 0:
        torch.distributed.barrier()
def create_dataloader(path, imgsz, batch_size, stride, opt, hyp=None, augment=False, cache=False, pad=0.0, rect=False,
                      rank=-1, world_size=1, workers=8, image_weights=False, quad=False, prefix=''):
    # Make sure only the first process in DDP process the dataset first, and the following others can use the cache
    with torch_distributed_zero_first(rank):
        dataset = LoadImagesAndLabels(path, imgsz, batch_size,
                                      augment=augment,  # augment images
                                      hyp=hyp,  # augmentation hyperparameters
                                      rect=rect,  # rectangular training
                                      cache_images=cache,
                                      single_cls=opt.single_cls,
                                      stride=int(stride),
                                      pad=pad,
                                      image_weights=image_weights,
                                      prefix=prefix)

理解

借助一个简单示例对with-as、yield相结合时的运行逻辑进行了理解。

简单示例:

from contextlib import contextmanager

#这段代码的作用是任何对列表的修改只有当所有代码运行完成并且不出现异常的情况下才会生效。
@contextmanager
def list_transaction(orig_list):
    working = list(orig_list)
    yield working
    orig_list[:] = working

items = [1, 2, 3]
with list_transaction(items) as f:
    f.append(6)
    f.append(7)
    raise RuntimeError('oops')

运行逻辑:

  1. 在with语句运行后,list_transaction运行到yield部分并抛出函数内的working赋值给f;
  2. 在with的作用域内,先向f内新增6、7元素,最后抛出RuntimeError;
  3. with作用域完成时,由于提前抛出了RuntimeError,list_transaction函数未能执行orig_list[:] = working

因为在with作用域内的所有语句执行完后,才会再次进入list_transaction函数执行yield后续的代码,因此with list_transaction(items) as f可以保证其作用域内对items列表的修改只有作用域内代码全部运行完成并且不出现异常的情况下才会生效。

参考

https://python3-cookbook.readthedocs.io/zh_CN/latest/c09/p22_define_context_managers_the_easy_way.html

相关文章

  • Python上下文管理器

    上下文管理器 概念:实现了上下文协议的对象即为上下文管理器。 上下文管理器的协议: __enter__进入的方法_...

  • python上下文管理器细读

    test 1 上下文管理器,将生成器转化为上下文管理器 test 2 使用上下文管理器,抽象出异常处理 test ...

  • python中上下文管理器

    什么是上下文管理器? 代码的环境就是上下文,实现了上下文管理器协议的类产生的实例就是上下文管理器对象。在类中声名e...

  • Python的上下文管理器

    什么是上下文管理器 上下文管理器是一个对象,它定义了在执行 with 语句时要建立的运行时上下文。 上下文管理器处...

  • Python学习打call第三十一天:上下文管理器

    1.什么是上下文管理 上下文管理器是一个包装任意代码块的对象,上下文管理器保证进入上下文管理器时,每次代码执行的一...

  • python 上下文管理器

    一、什么是上下文管理器? 上下文管理器类型是python的内置类型之一,上下文管理器的定义:允许用户自定义类来定义...

  • python的上下文管理器

    上下文管理器的概念 上下文管理器的任务是代码块执行前准备,代码块执行后收拾。 如何使用上下文管理器? 如何使用上下...

  • Python上下文管理器

    1.与装饰器的区别 上下文管理器是装饰器的近亲,装饰器用于包装函数,上下文管理器用于包装任意代码块. 上下文管理器...

  • 算法面试 - 问题记录

    python上下文管理器,装饰器? (1)上下文管理器知乎链接:https://zhuanlan.zhihu.co...

  • 关闭流要点2_with上下文管理_现场还原

    with语句(上下文管理器)with关键字(上下文管理器),可以自动管理上下文资源,无论什么原因跳出with块,都...

网友评论

      本文标题:上下文管理器

      本文链接:https://www.haomeiwen.com/subject/qndmfltx.html