Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling instances of a context manager inside another context manager

How should a context manager created inside another context manager be handled in Python?

Example: suppose you have class A that acts as a context manager, and class B that also acts as a context manager. But class B instances will have to instantiate and use an instance of class A. I've gone through PEP 343 and this is the solution I thought of:

class A(object):     def __enter__(self):         # Acquire some resources here         return self      def __exit__(seplf, exception_type, exception, traceback):         # Release the resources and clean up         pass   class B(object):     def __init__(self):         self.a = A()      def __enter__(self):         # Acquire some resources, but also need to "start" our instance of A         self.a.__enter__()         return self      def __exit__(self, exception_type, exception, traceback):         # Release the resources, and make our instance of A clean up as well         self.a.__exit__(exception_type, exception, traceback) 

Is this the correct approach? Or am I missing some gotchas?

like image 984
Sahand Avatar asked Jul 08 '14 16:07

Sahand


People also ask

Can context managers be used outside the with statement?

Yes, the context manager will be available outside the with statement and that is not implementation or version dependent. with statements do not create a new execution scope.

Which method pair are you required to implement in a context manager class?

Context managers can be written using classes or functions(with decorators). Creating a Context Manager: When creating context managers using classes, user need to ensure that the class has the methods: __enter__() and __exit__().

Which of the following module helps in creating a context manager using decorator context manager?

contextmanager() uses ContextDecorator so the context managers it creates can be used as decorators as well as in with statements.

What actions are guaranteed by a context manager?

Context managers allow you to allocate and release resources precisely when you want to. The most widely used example of context managers is the with statement. Suppose you have two related operations which you'd like to execute as a pair, with a block of code in between.


1 Answers

If you can use the @contextlib.contextmanager decorator your life gets a lot easier:

import contextlib  @contextlib.contextmanager def internal_cm():     try:         print "Entering internal_cm"         yield None         print "Exiting cleanly from internal_cm"     finally:         print "Finally internal_cm"   @contextlib.contextmanager def external_cm():     with internal_cm() as c:         try:             print "In external_cm_f", c             yield [c]             print "Exiting cleanly from external_cm_f", c         finally:             print "Finally external_cm_f", c   if "__main__" == __name__:     with external_cm():         print "Location A"     print     with external_cm():         print "Location B"         raise Exception("Some exception occurs!!") 
like image 99
kuzzooroo Avatar answered Oct 04 '22 12:10

kuzzooroo