4

I am trying to implement a class which uses a context manager.

Although I understand the general concept of __enter__ and __exit__, I don't see how to use the same context manager across multiple code blocks.

For example:

@contextmanager 
def backup_context(input)
    try:
        return xyz
    finally:
        revert(xyz)

class DoSomething:
    def __init__(self):
        self.context = context_val

    def do_resource_operation_1():
        with backup_context(self.context) as context:
            do_what_you_want_1(context)

    def do_resource_operation_2():
        with backup_context(self.context) as context:
            do_what_you_want_2(context)

I am invoking the context managers twice. I want to do only once during __init__ and use the same context manager object to do all my operations and then finally when the object is deleted I want to do the revert operation. How should i go about it?

Should I call __enter__ and __exit__ manually instead of using the with statement?

1
  • I don't know your broader use case, but it sounds like maybe your class should itself be a context manager. Commented Jun 30 at 19:00

1 Answer 1

0

Call the two methods you want inside the with statement block inside the __init__ method, like this:

@contextmanager 
def backup_context(input)
    try:
        return xyz
    finally:
        revert(xyz)
        
class DoSomething():
    def __init__(self, obj):
        self.obj = obj
        with backup_context(self.obj) as c:
            self.action1()
            self.action2()

    def action1(self):
        """action 1"""
        pass

    def action2(self):
        """action 2"""
        pass

Alternatively, if you really do want to perform the revert operation when the object is deleted, use a class with a __del__ method instead of using the @contextmanager decorator, like this:

class MyObject():
    def __init__(self):
        do_enter_action()

    def __del__(self):
        do_exit_action()
1
  • Using __del__ makes sense based on the description on the question, but I would caution that Python gives you no guarantee it will ever actually be called, even if there's bo exception and code runs to completion. I feel like that's probably a good portion of why context managers even exist in their current form. Commented Jun 30 at 19:03

Not the answer you're looking for? Browse other questions tagged or ask your own question.