0

I know that the with statement supports multiple context managers on the same level, like so:

with open('foo.txt') as foo, open('bar.txt') as bar:
    do_something()

But what if the list of context managers is getting too long for a single line? e.g.:

with open('foo.txt') as foo, open('bar.txt') as bar, open('bla.txt') as bla, open('yada.txt') as yada:
    do_something()

Currently, these are invalid syntax in Python 3.7:

with (
    open('foo.txt') as foo,
    open('bar.txt') as bar,
    open('bla.txt') as bla,
    open('yada.txt') as yada, # same thing without the last trailing comma
):
    do_something()
with 
    open('foo.txt') as foo,
    open('bar.txt') as bar,
    open('bla.txt') as bla,
    open('yada.txt') as yada, # same thing without the last trailing comma
:
    do_something()

I could do:

foo = open('foo.txt')
bar = open('bar.txt')
bla = open('bla.txt')
yada = open('yada.txt')

with foo, bar, bla, yada:
    do_something()

But even THAT could grow too long as I add more context managers.

I could also do:

with open('foo.txt') as foo:
    with open('bar.txt' as bar:
        with open('bla.txt' as bla:
            with open('yada.txt') as yada:
                do_something()

But it's ugly. It also lacks semantic hints for the human reader. There's a reason why we would want to put multiple context managers on the same level in the first place.

I know it's very uncommon for many context managers to belong to the same level, but it's definitely a possibility.

Kal
  • 1,707
  • 15
  • 29
  • 1
    how about https://stackoverflow.com/questions/3024925/create-a-with-block-on-several-context-managers does this help you? – Devesh Kumar Singh Jun 13 '19 at 05:03
  • 1
    Possible duplicate of [Create a "with" block on several context managers?](https://stackoverflow.com/questions/3024925/create-a-with-block-on-several-context-managers) – Azat Ibrakov Jun 13 '19 at 05:36
  • Using `ExitStack` seems like the cleanest solution, although it does mean extra setup lines. – Kal Jun 14 '19 at 02:12

1 Answers1

1

Line continuations are your friend here...

with \
    open('foo.txt') as foo, \
    open('bar.txt') as bar, \
    open('bla.txt') as bla, \
    open('yada.txt') as yada \
:
    do_something()

This is actually specifically mentioned in PEP-8.

ig0774
  • 39,669
  • 3
  • 55
  • 57
  • I'm going to mark this as the answer for now. It seems like a good compromise between the cleanest solution (using `ExitStack`) and convenience (no need for extra setup lines). – Kal Jun 14 '19 at 02:13