Question presented to candidate:
"Say you need to read from one file and write to another, and hold a lock while you do it. How do you manage all three with with? And what if the number of files is only known at run time?"
What a strong answer should cover:
with a() as x, b() as y:is exactly equivalent to nesting onewithinside another; the parenthesised, one-per-line form is official since Python 3.10.- Order: managers are entered left to right and exited right to left (last in, first out), so a later manager can use an earlier one.
- Failure part-way: if a later
__enter__raises, the managers already entered are still exited; the one that failed is not. - Exceptions travel inside out: the innermost
__exit__sees the error first and can suppress it, and then outer managers see a clean exit. contextlib.ExitStackfor a dynamic number of managers:enter_context(),callback(), andpop_all()for all-or-nothing acquisition;AsyncExitStackforasync with.- Look-alikes that are wrong:
with (a, b) as t:makes a tuple, andwith a and b:enters only one.
Clarifying questions expected:
- Is the number of resources fixed at write time, or does it depend on input?
- Must acquisition be all-or-nothing, and should the resources outlive the function that opens them?
Code / implementation expected: Yes β a comma-separated with showing enter/exit order, and an ExitStack loop over a list of resources.