Skip to content
Advertisement

Can we mix contextmanager decorator with __enter__() and __exit__() methods in another class inside the same with statement?

In python3.8 I’m very familiar with the traditional __enter__ and __exit__ magic methods but new to the @contextlib.contextmanager decorator. Is it possible to mix the two patterns inside a single with statement?

The following (highly contrived) script should explain the problem more clearly. Is there a definition of ContextClass.enter_context_function() and ContextClass.exit_context_function() (I imagine something needs to change inside __init__ as well) that only use the context_function() function and makes the unit tests pass? Or are these patterns mutually exclusive?

JavaScript

I understand there are better ways to solve a similar problem (specifically rewriting context_function as a class with its own __enter__ and __exit__ methods, but I’m trying to better understand exactly how the contextmanager decorator works.

Advertisement

Answer

No change in the __init__ is necessary. The manual way which “makes the unit tests pass” would be:

JavaScript

However, it’s kind of missing the point of context-managers. They’re intended to be used in a with-statement.

Also note that, as written, the NUMBERS.append(5) line (the “teardown”) may not be reached if the code after yielding raises. It should be written like this:

JavaScript
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement