On Thu, Nov 14, 2019 at 8:48 AM Eric Fahlgren <ericfahlgren@gmail.com> wrote:
I have used 'with' for so long that I was under the impression that the as-target was just a name as in MRAB's simplified syntax above, so imagine my surprise when I tried putting parentheses around the target and didn't get a syntax error straight away. I of course had to explore a bit, and came up with this. The ugly formatting of the with is simply to show that the parens behave as expected. class opener: def __init__(self, *files): self.files = [open(file) for file in files] def __enter__(self): return [file.__enter__() for file in self.files] def __exit__(self, *exc_info): for file in self.files: file.__exit__(*exc_info) return True
with opener( 'x', 'y', 'z' ) as ( f1, f2, f3 ): print(f1) print(f1.closed) print(f2) print(f3)
print(f1.closed)
Note that the semantics here are NOT the same as the semantics of either ExitStack or a single large 'with' statement. (And I'm not sure whether or not those two are the same.) With your opener, you first open each file, then enter each file; and only then are you considered to be inside the context. With a large 'with' statement, they should (I believe) be opened and entered individually. If one of the files fails to open, your constructor will fail, and self.files won't be set - you won't exit each of the files that you *did* open. ChrisA