On 18.11.2019 21:13, Barry wrote:
On 18 Nov 2019, at 19:27, Brendan Barnwell email@example.com wrote:
On 2019-11-18 10:49, Random832 wrote:
I would say open() is arguably a wart. Had context managers existed in the language all along, it should not be possible to do anything that creates an open-ended future requirement to do something (i.e. "require that the returned object gets closed at some stage") without either using a with statement or writing code to manually call __enter__ and __exit__. The likely most common case being a class that holds an open file, which should really have its own context manager that forwards to the file's.
I agree. I think this discussion wouldn't be necessary if there were a context manager that was like open() but opened the file in __enter__ and closed it in __exit__. I would go so far as to say I think it would be a good idea to add such a context manager to Python and deprecate open().
When I teach Python, I don't really even explain open() in isolation to students, I just tell them to always use it with a with statement. If I see code that uses open() outside a with statement it's a red flag to me. These hypothetical cases where you might want to use open() outside a with statement seem, to me, to be fairly esoteric. The best policy is for every file-opening operation to occur as part of a context manager,
Esoteric? I work with files that are open beyond the scope of a single block of code all the time. Clearly I need to arrange to close the file eventually. Why would I want the uglyness of __exit__ rather then close()? I use with all the time if the open() is with linear code.
Same here. In fact, I regularly have classes manage open files as part of their state, store it in instance attributes, have methods operate on it and close it either as part of the instance cleanup or explicitly in a .close() or .commit() method.
In fact, context managers themselves are often structured in this way and the OPs use case could also be handled by such a context manager class which groups resources.
While context managers are nice to define a block context, they are certainly not the only way to define the context of an operation.