On Aug 13, 2014 7:04 PM, "Akira Li" <4kir4.1i at gmail.com> wrote: > > Nick Coghlan <ncoghlan at gmail.com> writes: > > > On 12 August 2014 22:15, Steven D'Aprano <steve at pearwood.info> wrote: > >> 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 > > > > You wouldn't necessarily switch at three. At only three, you have lots > > of options, including multiple nested with statements: > > > > with open("spam") as spam: > > with open("eggs", "w") as eggs: > > with frobulate("cheese") as cheese: > > # do stuff with spam, eggs, cheese > > > > The "multiple context managers in one with statement" form is there > > *solely* to save indentation levels, and overuse can often be a sign > > that you may have a custom context manager trying to get out: > > > > @contextlib.contextmanager > > def dish(spam_file, egg_file, topping): > > with open(spam_file), open(egg_file, 'w'), frobulate(topping): > > yield > > > > with dish("spam", "eggs", "cheese") as spam, eggs, cheese: > > # do stuff with spam, eggs & cheese > > > > ExitStack is mostly useful as a tool for writing flexible custom > > context managers, and for dealing with context managers in cases where > > lexical scoping doesn't necessarily work, rather than being something > > you'd regularly use for inline code. > > > > "Why do I have so many contexts open at once in this function?" is a > > question developers should ask themselves in the same way its worth > > asking "why do I have so many local variables in this function?" > > Multiline with-statement can be useful even with *two* context > managers. Two is not many. > > Saving indentations levels along is a worthy goal. It can affect > readability and the perceived complexity of the code. > > Here's how I'd like the code to look like: > > with (open('input filename') as input_file, > open('output filename', 'w') as output_file): > # code with list comprehensions to transform input file into output file > > Even one additional unnecessary indentation level may force to split > list comprehensions into several lines (less readable) and/or use > shorter names (less readable). Or it may force to move the inline code > into a separate named function prematurely, solely to preserve the > indentation level (also may be less readable) i.e., > > with ... as input_file: > with ... as output_file: > ... #XXX indentation level is lost for no reason > > with ... as infile, ... as outfile: #XXX shorter names > ... > > with ... as input_file: > with ... as output_file: > transform(input_file, output_file) #XXX unnecessary function > > And (nested() can be implemented using ExitStack): > > with nested(open(..), > open(..)) as (input_file, output_file): > ... #XXX less readable > > Here's an example where nested() won't help: > > def get_integers(filename): > with (open(filename, 'rb', 0) as file, > mmap.mmap(file.fileno(), 0, access=mmap.ACCESS_READ) as mmapped_file): > for match in re.finditer(br'\d+', mmapped_file): > yield int(match.group()) > > Here's another: > > with (open('log'+'some expression that generates filename', 'a') as logfile, > redirect_stdout(logfile)): > ... > Just a thought, would it bit wierd that: with (a as b, c as d): "works" with (a, c): "boom" with(a as b, c): ? > > -- > Akira > > _______________________________________________ > Python-Dev mailing list > Python-Dev at python.org > https://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: https://mail.python.org/mailman/options/python-dev/yoavglazner%40gmail.com -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.python.org/pipermail/python-dev/attachments/20140813/0f7908cc/attachment-0001.html>
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4