Reusing multiple contexts in Python 'with' statement












0














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









share|improve this question


















  • 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.)
    – user2357112
    Nov 15 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...
    – Jon Clements
    Nov 15 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.
    – DikobrAz
    Nov 15 at 23:04
















0














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









share|improve this question


















  • 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.)
    – user2357112
    Nov 15 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...
    – Jon Clements
    Nov 15 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.
    – DikobrAz
    Nov 15 at 23:04














0












0








0







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









share|improve this question













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






python python-3.x with-statement






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 15 at 22:53









DikobrAz

1,6572038




1,6572038








  • 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.)
    – user2357112
    Nov 15 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...
    – Jon Clements
    Nov 15 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.
    – DikobrAz
    Nov 15 at 23:04














  • 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.)
    – user2357112
    Nov 15 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...
    – Jon Clements
    Nov 15 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.
    – DikobrAz
    Nov 15 at 23:04








1




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.)
– user2357112
Nov 15 at 23:00




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.)
– user2357112
Nov 15 at 23:00




1




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...
– Jon Clements
Nov 15 at 23:02






@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...
– Jon Clements
Nov 15 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.
– DikobrAz
Nov 15 at 23:04




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.
– DikobrAz
Nov 15 at 23:04












2 Answers
2






active

oldest

votes


















2














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)





share|improve this answer























  • But then you're returning two closed files.
    – user2357112
    Nov 15 at 23:00






  • 1




    I think you're missing @contextlib.contextmanager now.
    – user2357112
    Nov 15 at 23:02






  • 1




    Also parentheses around the f1,f2 in with files() as f1,f2, or the precedence isn't going to work the way you want.
    – user2357112
    Nov 15 at 23:03










  • lol thanks :P ..
    – Joran Beasley
    Nov 15 at 23:03



















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.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53329005%2freusing-multiple-contexts-in-python-with-statement%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    2














    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)





    share|improve this answer























    • But then you're returning two closed files.
      – user2357112
      Nov 15 at 23:00






    • 1




      I think you're missing @contextlib.contextmanager now.
      – user2357112
      Nov 15 at 23:02






    • 1




      Also parentheses around the f1,f2 in with files() as f1,f2, or the precedence isn't going to work the way you want.
      – user2357112
      Nov 15 at 23:03










    • lol thanks :P ..
      – Joran Beasley
      Nov 15 at 23:03
















    2














    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)





    share|improve this answer























    • But then you're returning two closed files.
      – user2357112
      Nov 15 at 23:00






    • 1




      I think you're missing @contextlib.contextmanager now.
      – user2357112
      Nov 15 at 23:02






    • 1




      Also parentheses around the f1,f2 in with files() as f1,f2, or the precedence isn't going to work the way you want.
      – user2357112
      Nov 15 at 23:03










    • lol thanks :P ..
      – Joran Beasley
      Nov 15 at 23:03














    2












    2








    2






    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)





    share|improve this answer














    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)






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 15 at 23:03

























    answered Nov 15 at 22:59









    Joran Beasley

    72.2k677116




    72.2k677116












    • But then you're returning two closed files.
      – user2357112
      Nov 15 at 23:00






    • 1




      I think you're missing @contextlib.contextmanager now.
      – user2357112
      Nov 15 at 23:02






    • 1




      Also parentheses around the f1,f2 in with files() as f1,f2, or the precedence isn't going to work the way you want.
      – user2357112
      Nov 15 at 23:03










    • lol thanks :P ..
      – Joran Beasley
      Nov 15 at 23:03


















    • But then you're returning two closed files.
      – user2357112
      Nov 15 at 23:00






    • 1




      I think you're missing @contextlib.contextmanager now.
      – user2357112
      Nov 15 at 23:02






    • 1




      Also parentheses around the f1,f2 in with files() as f1,f2, or the precedence isn't going to work the way you want.
      – user2357112
      Nov 15 at 23:03










    • lol thanks :P ..
      – Joran Beasley
      Nov 15 at 23:03
















    But then you're returning two closed files.
    – user2357112
    Nov 15 at 23:00




    But then you're returning two closed files.
    – user2357112
    Nov 15 at 23:00




    1




    1




    I think you're missing @contextlib.contextmanager now.
    – user2357112
    Nov 15 at 23:02




    I think you're missing @contextlib.contextmanager now.
    – user2357112
    Nov 15 at 23:02




    1




    1




    Also parentheses around the f1,f2 in with files() as f1,f2, or the precedence isn't going to work the way you want.
    – user2357112
    Nov 15 at 23:03




    Also parentheses around the f1,f2 in with files() as f1,f2, or the precedence isn't going to work the way you want.
    – user2357112
    Nov 15 at 23:03












    lol thanks :P ..
    – Joran Beasley
    Nov 15 at 23:03




    lol thanks :P ..
    – Joran Beasley
    Nov 15 at 23:03













    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.






    share|improve this answer




























      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.






      share|improve this answer


























        2












        2








        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.






        share|improve this answer














        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.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        answered Nov 15 at 23:13


























        community wiki





        chepner































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53329005%2freusing-multiple-contexts-in-python-with-statement%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

            ComboBox Display Member on multiple fields

            Is it possible to collect Nectar points via Trainline?