1

In Python3 we can use multiple contexts in with statements. But is it possible to enter multiple contexts if they can't be constructed right away in the with statement? Is it possible to do something like this?

def files():
    return open('a.txt', 'w'), open('b.txt', 'w')

with files():
    pass

Or this:

files = open('a.txt', 'w'), open('b.txt', 'w')
with files:
    pass
3
  • 1
    That's an unsafe pattern - if something goes wrong while opening the second file, the first doesn't get closed. If you give more detail about why you're trying to do this, we can probably give you a better option. (ExitStack is likely to be involved.) Commented Nov 15, 2018 at 23:00
  • 1
    @user2357112 yeah... was going to suggest having a look at contextlib.ExitStack as that's my gut feeling but I'm still not sure what the use case is... Commented Nov 15, 2018 at 23:02
  • Is there a way to make it safe, e.g. to replicate the behavior of with open(...), open().... Maybe saving context into variable is not nice, but pattern with a function should be fairy safe. Commented Nov 15, 2018 at 23:04

2 Answers 2

3
from contextlib import contextmanager

@contextmanager
def files():
    with open('a.txt', 'w') as f1, open('b.txt', 'w') as f2:
         yield f1,f2

maybe?

with files() as (f1,f2):
     print(f1,f2)
Sign up to request clarification or add additional context in comments.

2 Comments

But then you're returning two closed files.
Also parentheses around the f1,f2 in with files() as f1,f2, or the precedence isn't going to work the way you want.
2

An example using contextlib.ExitStack:

from contextlib import ExitStack

def files(stack, *args):
    return [stack.enter_context(open(f, "w")) for f in args]

with ExitStack() as stack:
    f1, f2 = files(stack, "a.txt", "b.txt")
    ...

or without the wrapper

with ExitStack() as stack:
    f1, f2 = [stack.enter_context(open(f, "w")) for f in ["a.txt", "b.txt"]]
    ...

However, when you know how many files are to be opened ahead of time (and it's a small number of files), the multiple manager form of the with statement as shown in Joran Beasley's answer is simpler.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.