Domanda

Suppose I have a context manager:

@contextmanager
def cm(x):
    y = f(x)
    z = yield y
    g(z)

How do I send z into the context manager?

I tried:

my_cm = cm()
with my_cm:
    my_cm.gen.send(123)

but I get StopIteration, which might be because send yields?

È stato utile?

Soluzione

@contextmanager returns a helper function that in turn returns a GeneratorContextManager instance, that uses your generator as a way to manage the context.

It is not intended to be used as anything you can send to, next() is called in __enter__. You could try and access the underlying generator with the .gen attribute:

my_cm.gen.send(123)

but you'd have to include an extra yield statement to prevent the method from exiting prematurely. Note that __exit__ will call next() once more to conclude the generator.

@contextmanager
def cm(x):
    y = f(x)
    a = yield y   # Run for `__enter__`, returning `y`; `.send()` resumes here
    yield         # Here we pause again
    g(a)

works, in that it has a second yield to pause the generator again until the context manager is ready to call next() one last time.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top