ReviseAlgo Logo

File Handling

with Statement for Files

Context managers and the with statement for safe, automatic resource cleanup when working with files and other resources.

Interview: Essential best practice — interviewers expect you to use with for file handling and understand the context manager protocol.

Last Updated: June 12, 2026 10 min read

The with statement is Python's mechanism for deterministic resource management. It guarantees that resources are cleaned up when the block is exited — whether normally or via an exception — eliminating the most common source of resource leaks in Python programs.

Why the with Statement Matters

Without with, you must manually close files in a finally block. This is error-prone and verbose:

  • Resource leaks: Forgetting to close files wastes file descriptors and memory
  • Exception safety: If an error occurs between open() and close(), the file stays open
  • Verbosity: Manual try/finally blocks add boilerplate code
  • The with statement solves all three problems with clean, readable syntax

Basic Usage

The with statement calls __enter__() when entering the block and __exit__() when leaving — even if an exception occurs:

  • __enter__() — returns the resource (the file object)
  • __exit__(exc_type, exc_val, traceback) — handles cleanup; receives exception info if one occurred
  • If __exit__ returns True, the exception is suppressed
  • File objects' __exit__ always calls close() regardless of exceptions

Multiple Files in One with Statement

Python 3.10+ supports parenthesized context managers. You can open multiple files in a single with statement:

  • Use comma-separated context managers on one line (or parenthesized for readability)
  • All files are closed in reverse order when the block exits
  • This is cleaner than nested with statements

Custom Context Managers

You can create your own context managers using a class (with __enter__/__exit__) or the @contextmanager decorator:

  • Class-based: Implement __enter__ and __exit__ methods
  • Generator-based: Use @contextmanager from contextlib — yield separates setup from teardown
  • Use cases: Database connections, locks, temporary directories, timing, logging

Interview Insight

Interviewers often ask "What happens if an exception occurs inside a with block?" The answer: the file is still closed because __exit__ is always called. You should also know how to write custom context managers and explain the difference between class-based and generator-based approaches.

Use Cases

File reading/writing — ensures files are always closed

Database connections — automatic commit/rollback and connection closing

Thread locks — automatic lock acquisition and release

Temporary resources — temp files, directories, or network connections

Timing and profiling — measure execution time of code blocks

Common Mistakes

Using open() without with — leads to resource leaks if you forget close()

Not knowing that __exit__ is called even on exceptions — the file IS closed

Nesting too many with statements — use multiple context managers on one line instead

Returning True from __exit__ accidentally — this suppresses exceptions silently

Forgetting that yield in @contextmanager must appear exactly once