On Aug 13, 2014 7:04 PM, "Akira Li" <4kir4...@gmail.com> wrote: > > Nick Coghlan <ncogh...@gmail.com> writes: > > > On 12 August 2014 22:15, Steven D'Aprano <st...@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@python.org > https://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: https://mail.python.org/mailman/options/python-dev/yoavglazner%40gmail.com
_______________________________________________ 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