[Python] Context managers as attributes

Discussão em 'Python' iniciado por Stack, Abril 25, 2025.

  1. Stack

    Stack Membro Participativo

    I am having a hard time to write clean code with context managers in Python without getting in a context manager hell. Imagine something like:

    class A:
    def __init__(self):
    self.b = B() # where B is a context manager


    This leaks now, because I did not use a with statement. In the wild I have seen two solutions to this:


    1. Inject B in the class and have some outer with statement

      with B() as b:
      a = A(b)

    2. Make A a context manager as well that implements closing B:

      with A() as a:
      ...
      # A will close B now in its __exit__ method

    I dislike both methods. In my example the usage of B inside of A is an implementation detail. It is not something I want to expose to the outer world. Thus, Option 1 is obviously not suitable, but even Option 2 exposes some details. Mainly that A does some resource management. Additionally having to manually implement the __exit__ method does seem to defeat a little bit the purpose of B being a context manager, if I cannot use the context manager syntax.

    So I am sort of missing the C++ RAII here I think, which is not directly suitable for Python. So how can I avoid making basically all my classes context managers if there is a dependency chain?

    To give a very concrete use case:

    An ML agent (like ChatGPT) wants to execute code. So I might have a class Agent that can execute code. This is done with jupyter notebook. Thus my program needs a jupyter notebook server running. Ideally I would like to encapsulate this within the Agent class. The Agent class starts the server and stops the server. The server here is implemented as a context manager. The solution I would come up with is making the Agent now a context manager too, which I dislike. Because then some class using the Agent needs to become a context manager too, ... so in the end my whole program is a context manager.

    Continue reading...

Compartilhe esta Página