(no title)
tomn | 10 months ago
The main one is that it makes error handling and clean-up simpler, because you can just wrap the yield with a normal try/catch/finally, whereas to do this with __enter__ and __exit__ you have to work out what to do with the exception information in __exit__, which is easy to get wrong:
https://docs.python.org/3/reference/datamodel.html#object.__...
Suppressing or passing the exception is also mysterious, whereas with contextlib you just raise it as normal.
Another is that it makes managing state more obvious. If data is passed into the context manager, and needs to be saved between __enter__ and __exit__, that ends up in instance variables, whereas with contextlib you just use function parameters and local variables.
Finally, it makes it much easier to use other context managers, which also makes it look more like normal code.
Here's a more real-world-like example in both styles:
https://gist.github.com/tomjnixon/e84c9254ab6d00542a22b7d799...
I think the first is much more obvious.
You can describe it in english as "open a file, then try to write a header, run the code inside the with statement, write a footer, and if anything fails truncate the file and pass the exception to the caller". This maps exactly to the lines in the contextlib version, whereas this logic is all spread out in the other one.
It's also more correct, as the file will be closed if any operation on it fails -- you'd need to add two more try/catch/finally blocks to the second example to make it as good.
No comments yet.