The goal of Python's with statement is syntactic sugar to properly manage external resources to your script such as files, locks, network connections, and others. You have to manage these resources; otherwise, a script will retain those resources forever causing a memory leak. The problem with the regular paradigm of
- file = open...
- file.write...
- file.close()
occurs if an error occurs during the file.write call, then file.close will never be called causing an issue. In Python, there are generally two ways to deal with these issue.
- A try...finally construct
- A with construct
This second approach provides a [design] pattern to generate setup and teardown code as long as the resource that you are managing works with Python context manager paradigm. The reason for this is due to Python's with clause embodying C++'s well known "resource acquisition if initialization" paradigm (RAII): You need only write context manager classes--that is, classes with two special methods (dunder methods in Python terminology) enter and exit . enter must be callable without arguments. exit must be callable with three arguments: all None if the body completes without propagating exceptions, and otherwise the type, value, and traceback of the exception. This provides the same guaranteed finalization behavior as typical ctor/dtor pairs have for auto variables in C++, and try/finally statements have in Python or Java. In addition, you gain the ability to finalize differently depending on what exception, if any, propagates, as well as optionally blocking a propagating exception by returning a True value from exit.
Hope this helps and good-luck!