Python
with statement
context management
multiple variables
programming tips

Multiple variables in a 'with' statement?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Yes, Python allows multiple context managers in a single with statement. This is a normal and idiomatic way to manage several resources at once when they all have clear setup and teardown behavior.

The important detail is that multiple context managers are entered from left to right and exited in reverse order. That ordering matters when the resources depend on each other.

Basic Syntax

The syntax looks like this:

python
with open("input.txt") as source, open("output.txt", "w") as target:
    for line in source:
        target.write(line.upper())

This is equivalent to nested with blocks:

python
1with open("input.txt") as source:
2    with open("output.txt", "w") as target:
3        for line in source:
4            target.write(line.upper())

Both are correct. The single-line form is shorter and often easier to read when the context managers are simple.

How Entry and Exit Order Works

Python evaluates multiple context managers left to right:

  1. open the first one
  2. open the second one
  3. run the body
  4. close the second one
  5. close the first one

That reverse exit behavior mirrors nested with blocks exactly. This matters if later resources depend on earlier ones.

For example, if one context manager creates a transaction and another creates a cursor inside it, the cursor should usually close before the transaction does. Python’s ordering handles that naturally.

Assigning Multiple Variables

Each context manager can bind its own variable with as:

python
with open("a.txt") as a, open("b.txt") as b:
    print(a.read())
    print(b.read())

You are not limited to files. Any object that implements the context manager protocol works the same way.

Example With Locks

Here is a non-file example using two locks:

python
1from threading import Lock
2
3lock_a = Lock()
4lock_b = Lock()
5
6with lock_a, lock_b:
7    print("Both locks held")

This is valid, but it also shows why ordering matters. In concurrent code, inconsistent lock ordering can create deadlocks, so even elegant syntax still needs sound resource design.

When a Single with Statement Is Best

A single with statement is usually best when:

  • the number of context managers is fixed
  • each one is simple
  • and the line remains readable

For example, two or three files, or a connection and cursor pair, are usually fine in one statement.

If the line becomes long or the setup gets complicated, nested with blocks may read better.

Dynamic Numbers of Context Managers With ExitStack

If you do not know in advance how many context managers you need, use contextlib.ExitStack.

python
1from contextlib import ExitStack
2
3filenames = ["a.txt", "b.txt", "c.txt"]
4
5with ExitStack() as stack:
6    files = [stack.enter_context(open(name)) for name in filenames]
7    for f in files:
8        print(f.readline().strip())

This is the right tool when the count is dynamic. A normal with statement expects a fixed number of context managers written in code.

Exception Behavior

If an exception happens inside the with block, Python still unwinds the context managers in reverse order. That is one of the main reasons with exists at all.

If one of the later context managers fails during setup, already-opened earlier ones are cleaned up automatically. That is another reason the syntax is safer than manual setup and teardown code.

Common Pitfalls

One common mistake is assuming the resources are exited in the same order they were entered. They are not. Exit happens in reverse order.

Another mistake is forcing too many complex context managers onto one line until the code becomes harder to read than nested blocks.

It is also easy to use a normal multi-manager with when the number of resources is dynamic. That is what ExitStack is for.

Finally, elegant syntax does not remove logical dependencies. If two resources have ordering or concurrency constraints, you still need to design those correctly.

Summary

  • Python supports multiple context managers in one with statement.
  • They are entered from left to right and exited from right to left.
  • The syntax is equivalent to nested with blocks.
  • Use the single statement form when the number of resources is fixed and readable.
  • Use ExitStack when the number of context managers is dynamic.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.