I have searched and I'm unable to come up with any good reason to use python's __enter__
/__exit__
rather than __init__
(or __new__
?) / __del__
.
I understand that __enter__
/ __exit__
are intended for use with the with
statement as context managers, and the with
statement is great. But the counterpart to that is that any code in those blocks is only executed in that context. By using these instead of __init__
/ __del__
I appear to be creating an implicit contract with callers that they must use with
, yet there's no way to enforce such a contract, and the contract is only communicated via documentation (or reading the code). That seems like a bad idea.
I seem to get the same effect using __init__
/ __del__
inside of a with
block. But by using them rather than the context management methods my object is also useful in other scenarios.
So can anybody come up with a compelling reason why I would ever want to use the context management methods rather than the constructor/destructor methods?
If there's a better place to ask a question like this, please let me know, but it seems like there's not much good information about this out there.
Follow Up:
This question was based on a bad (but likely common) assumption because I always used with
to instantiate a new object, in which case __init__/__del__
come very close to the same behavior as __enter__/__exit__
(except that you can't control when or if __del__
will be executed, it's up to garbage collection and if the process is terminated first it may never be called). But if you use pre-existing objects in with
statements they are of course quite different.