constructor - Python __enter__ / __exit__ vs __init__ (or __new__) / __del__ -
i have searched , i'm unable come reason use python's __enter__ /__exit__ rather __init__ (or __new__ ?) / __del__ .
i understand __enter__ / __exit__ intended use with statement context managers, , with statement great. counterpart code in blocks only executed in context. using these instead of __init__ / __del__ appear creating implicit contract callers must use with, yet there's no way enforce such contract, , contract communicated via documentation (or reading code). seems bad idea.
i seem same effect using __init__ / __del__ inside of with block. using them rather context management methods object useful in other scenarios.
so can come compelling reason why ever want use context management methods rather constructor/destructor methods?
if there's better place ask question this, please let me know, seems there's not information out there.
follow up:
this question based on bad (but common) assumption because used with instantiate new object, in case __init__/__del__ come close same behavior __enter__/__exit__ (except can't control when or if __del__ executed, it's garbage collection , if process terminated first may never called). if use pre-existing objects in with statements of course quite different.
there several differences appear have missed:
context manager chance provide new object block executing. context managers return
selfthere (like file objects do), database connection objects return cursor object tied current transaction.context managers notified notified of context ending, if exit caused exception. can decide on handling event or otherwise react differently during exit. using database connection example again, based on there being exception either commit or abort transaction.
__del__called when all references object removed. means can't rely on being called if need have multiple references may or may not control lifetime of. context manager exit precisely defined however.context managers can reused, , can keep state. database connection again; create once, use context manager again , again, , it'll keep connection open. there no need create new object each time this.
this important thread locks, example; have keep state 1 thread can hold lock @ time. creating one lock object, use
with lock:different threads executing section each can made wait before entering context.
the __enter__ , __exit__ methods form context manager protocol, , should use these if want manage context. goal of context managers simplify common try...finally , try...except patterns, not manage lifetime of single instance. see pep 343 – the "with" statement:
this pep adds new statement "with" python language make possible factor out standard uses of try/finally statements.
Comments
Post a Comment