Python __enter__ / __exit__ vs __init__ (or __new__) / __del__
<p>I have searched and I'm unable to come up with any good reason to use python's <code>__enter__</code> /<code>__exit__</code> rather than <code>__init__</code> (or <code>__new__</code> ?) / <code>__del__</code> .</p>

<p>I understand that <code>__enter__</code> / <code>__exit__</code> are intended for use with the <code>with</code> statement as context managers, and the <code>with</code> statement is great. But the counterpart to that is that any code in those blocks is <em>only</em> executed in that context. By using these instead of <code>__init__</code> / <code>__del__</code> I appear to be creating an implicit contract with callers that they must use <code>with</code>, 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.</p>

<p>I seem to get the same effect using <code>__init__</code> / <code>__del__</code> inside of a <code>with</code> block. But by using them rather than the context management methods my object is also useful in other scenarios.</p>

<p>So can anybody come up with a compelling reason why I would <em>ever</em> want to use the context management methods rather than the constructor/destructor methods?</p>

<p>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.</p>

<h1><em>Follow Up:</em></h1>

<p><em>This question was based on a bad (but likely common) assumption because I always used <code>with</code> to instantiate a new object, in which case <code>__init__/__del__</code> come very close to the same behavior as <code>__enter__/__exit__</code> (except that you can't control when or if <code>__del__</code> 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 <code>with</code> statements they are of course quite different.</em></p>