生成器和上下文管理器同时 [英] Generator and context manager at the same time

查看:65
本文介绍了生成器和上下文管理器同时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

想象一下,我有一些要运行的代码:

Imagine I have some code that I want it to run:

with F() as o:
    while True:
        a = o.send(2)
        print(a)

这意味着 F 类应该返回一个 generator ,并且它也是 context manager ,通常我希望上下文管理器是生成器也是.

It means that the F class should return an generator and also it is context manager, generally I want a context manager to be generator too.

我尝试过:

class F:

    def __enter__(self):
        return self

    def __exit__(self, *exc):
        print('exit')

    def __next__(self):
        return 5

    def __iter__(self):
        return self

按预期,这将返回 AttributeError:'F'对象没有属性'send',我通过添加以下内容来处理此错误:

As expected this will return AttributeError: 'F' object has no attribute 'send', I handled this error by adding:

def send(self, param):
    self.__next__()

但是我认为这不是一个好方法,我环顾四周,找到 ,但是他们没有按照我的要求使用 send ,我需要该实例作为生成器.

but I think it is not a good way to do this, I look around and find this, but they are not using send as I want, I need that instance to be a generator.

推荐答案

您可以使用 collections.abc 并从 Generator 继承类 F >(手册页).如果您实现 enter exit ,则您的实例将是生成器,并且还具有上下文管理器支持:

You can use collections.abc and subclass your class F from Generator (manual pages). If you implement enter and exit, your instance will be generator and have context manager support as well:

from collections.abc import Generator

class F(Generator):
    def __init__(self):
        self.__my_generator = self._my_generator()
        next(self.__my_generator)   # prime the generator

    def _my_generator(self):
        while True:
            v = yield 42
            print('generator received ', v)

    # context manager interace:
    def __enter__(self):
        return self

    def __exit__(self, *exc):
        print('exit')

    # Generator interface:
    def send(self, value):
        return self.__my_generator.send(value)

    def throw(self, typ, value=None, traceback=None):
        return self.__my_generator.throw(typ, value, traceback)


with F() as o:
    while True:
        a = o.send(2)
        print('I received ', a)

打印:

generator received  2
I received  42
...etc.

这篇关于生成器和上下文管理器同时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆