1

I am trying to find a good way to explain why creating an specialized context manager by calling another one works as expected. I am not complaining!, it is great that it does. But I was not sure if that it would work until I tested it and therefore I feel I am loosing something.

Just to clarify considere the following example:

>>> from contextlib import contextmanager
>>> @contextmanager
... def f(val):
...    print(val)
...    yield
...    print(val+1)
...
>>>
>>> with f(1):
...  print(3)
...
1
3
2

And now we specialize it:

>>> def f42():
...    return f(42)
...
>>> with f42():
...    print(3)
...
42
3
43

I guess what is confusing me is why does the yield from f bubbles up through f42? Why I do not need to write f42 as a context manager explicitly.

0

2 Answers 2

1

There is no difference between using f(42) in a with statement and using it in another function then returning it. All that with requires is that the expression produces a context manager.

You could also do this:

cm = f(42)
with cm:
    print(3)

All that Python does is execute the expression in the with <expression> statement and then treats the result of that expression as a context manager. How the expression produced that context manager is of no consequence.

In other words, f is not your context manager here, only the return value of a call to f().

Sign up to request clarification or add additional context in comments.

Comments

1

In your last with statement, f42() gets evaluated and runs f(42) which is then used in the context of your with statement.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.