4 ms·
`using` composes badly. It won't work with eg. a list of Disposables or Linq.
by noctune 6y ago
`using` composes badly. It won't work with eg. a list of Disposables or Linq.
- ben509 6y agoThis is the strongest argument against claiming "using" or Python's context managers are RAII. RAII naturally composes because a container has to clean up its memory, and it has a well defined lifetime. Python has a very straightforward model for its context managers, two magic methods: def __enter__(self): ... def __exit__(self, etype, eval, tb): ... To handle many resources being released, the stdlib prefers a more direct approach using a special class: with ExitStack() as stack: files = [stack.enter_context(open(fname)) for fname in filenames] And it makes sense. You probably don't want regular containers to have yet another magic method defined on them, and there is no clear single behavior the a container's __enter__ and __exit__ method could have. And it doesn't compose in other ways. In async code, for instance, there's a completely separate mechanism with `async with` that calls __aenter__ and __aexit__. It really comes down to the fact that when objects have an ambiguous lifetime, which is a consequence of garbage collection, you can't have RAII.