Are multiple `with` statements on one line equivalent to nested `with` statements, in python?
Asked Answered
E

3

39

Are these two statements equivalent?

with A() as a, B() as b:
  # do something

with A() as a:
  with B() as b:
    # do something

I ask because both a and b alter global variables (tensorflow here) and b depends on changes made by a. So I know the 2nd form is safe to use, but is it equivalent to shorten it to the 1st form?

Elsey answered 31/3, 2017 at 1:33 Comment(0)
E
55

Yes, listing multiple with statements on one line is exactly the same as nesting them, according to the Python 2.7 language reference:

With more than one item, the context managers are processed as if multiple with statements were nested:

with A() as a, B() as b:
   suite

is equivalent to

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

Similar language appears in the Python 3 language reference.

Update for 3.10+

Changed in version 3.10: Support for using grouping parentheses to break the statement in multiple lines.

with (
   A() as a,
   B() as b,
):
   SUITE
Erny answered 31/3, 2017 at 1:36 Comment(4)
@Nabin: If there is any difference at all, it will be very slight. Python is not designed for micro-optimization, so any difference will not matter in practice.Erny
With due respect, I would not expect someone with 18.8k to say this. I always look for the optimal piece of code in python.Salvatore
@Nabin: You are wrong to do so. Python is a slow, high-level language. Micro-optimization is a net loss of time. Regardless, I tried putting both versions into dis.dis() and they generated identical bytecode.Erny
what if you are trying to get two semaphores, will it only get one if it can get the other, or will it get the outer one, then wait for the inner?Januaryjanuisz
C
6

As others have said, it's the same result. Here's a more detailed example of how this syntax might be used:

blah.txt

1
2
3
4
5

I can open one file and write its contents to another file in a succinct manner:

with open('blah.txt', 'r') as infile, open('foo.txt', 'w+') as outfile:
    for line in infile:
        outfile.write(str(line))

foo.txt now contains:

1
2
3
4
5
Caracaraballo answered 31/3, 2017 at 1:47 Comment(3)
I like the example, and appreciate it. However I feel a bit compelled to point out that the order in which you open blah and foo wouldn't actually matter in this case, thus defeating the point of the example.Elsey
@DavidParks I never said the order in which either file is opened would matter. You could open the outfile first and infile second... Whatever you want to do. I provided the example to demonstrate how this syntax enables tasks like the above to be done in a very readable way. The "point of the example" isn't defeated.Caracaraballo
Agreed, and it's a good and relevant example, my question in particular was specific to order, that's why I commented. But as a general point about how it works, I'm sure it will be a useful reference to others that may stumble across this, so thanks for taking the time to add it!Elsey
F
0

For those using < python 3.9, you can always still split them between multiple lines with \, though this may not look as good as using grouping parentheses.

with A() as a, \
     B() as b, \
     C() as c:
    suite
Freaky answered 27/6, 2023 at 23:41 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.