On Tue, Aug 12, 2014 at 10:28:14AM +1000, Nick Coghlan wrote: > On 12 Aug 2014 09:09, "Allen Li" <cyberdup...@gmail.com> wrote: > > > > This is a problem I sometimes run into when working with a lot of files > > simultaneously, where I need three or more `with` statements: > > > > with open('foo') as foo: > > with open('bar') as bar: > > with open('baz') as baz: > > pass > > > > Thankfully, support for multiple items was added in 3.1: > > > > with open('foo') as foo, open('bar') as bar, open('baz') as baz: > > pass > > > > However, this begs the need for a multiline form, especially when > > working with three or more items: > > > > with open('foo') as foo, \ > > open('bar') as bar, \ > > open('baz') as baz, \ > > open('spam') as spam \ > > open('eggs') as eggs: > > pass > > I generally see this kind of construct as a sign that refactoring is > needed. For example, contextlib.ExitStack offers a number of ways to manage > multiple context managers dynamically rather than statically.
I don't think that ExitStack is the right solution for when you have a small number of context managers known at edit-time. The extra effort of writing your code, and reading it, in a dynamic manner is not justified. Compare the natural way of writing this: with open("spam") as spam, open("eggs", "w") as eggs, frobulate("cheese") as cheese: # do stuff with spam, eggs, cheese versus the dynamic way: with ExitStack() as stack: spam, eggs = [stack.enter_context(open(fname), mode) for fname, mode in zip(("spam", "eggs"), ("r", "w")] cheese = stack.enter_context(frobulate("cheese")) # do stuff with spam, eggs, cheese I prefer the first, even with the long line. -- Steven _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com