On Nov 15, 2019, at 04:37, Jonathan Fine <[email protected]> wrote:
>
>
> Serhiy suggests
> https://docs.python.org/3/library/contextlib.html#contextlib.ExitStack
> >>> with ExitStack() as stack:
> >>> files = [stack.enter_context(open(fname)) for fname in filenames]
>
> A simpler alternative, for the OP's original post, could be:
> >>> with ExitMap(open, ['a', 'b', 'c']) as a, b, c:
> >>> pass
> where ExitMap(*args) is equivalent to helper(map(*args)). Of course, using
> ExitStack is the easy way to code ExitMap.
The advantage of your ExitMap over helper (besides being shorter, and
conceptually simpler) is that it’s never misleading.
with helper(open(fn) for fn in (fna, fnb, fnc)) as a, b, c:
This is fine. If open(fnb) raises, helper has already stacked up open(fna) and
can exit it. But change the genexpr to a listcomp:
with helper([open(fn) for fn in (fna, fnb, fnc)]) as a, b, c:
This looks the same, and seems fine if you don’t test error cases, but if
open(fnb) fails, helper never gets called so nothing gets stacked up so
open(fna) leaks.
And calling it with an iterable you create out-of-line can make it even more
confusing because it’s not as clear where to look when you accidentally make
the iterable not lazy. Not to mention that it could even be a properly lazy
Iterator but one that needs to be fully consumed for your program logic (not an
issue for a simple map over a tuple of strings), and that would be an even more
subtle bug.
If you could clearly document and/or test for the requirements, maybe helper
would be useful. But your ExitMap doesn’t rely on you correctly building the
right iterator; it builds the Iterator itself, and doesn’t expose parts that
can be misused. So it’s trivial to document, and to learn and use.
It still seems like overkill for the case of “how do I get parens somewhere
around a bunch of open calls so I can write a multiline with statement”, and
I’m not sure how often it would be useful in other cases. But it seems like
it’s at least worth building for your personal toolbox and keeping track of how
often it comes up (and how much nicer it makes things), and maybe publishing it
to PyPI or submitting it to contextlib2 so more people will do the same.
_______________________________________________
Python-ideas mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/YCYW7U2F3WW36TOOBAWMTEW7QUMHDRGB/
Code of Conduct: http://python.org/psf/codeofconduct/