ho secondo l'idea generale di utilizzare i gestori di contesto e la with
dichiarazione invece di basarsi su __del__
(per le stesse ragioni si preferisce try/finally ai metodi Finalizer in Java, più uno: in Python, la presenza di __del__
metodi può rendere la raccolta cicliche non recuperabile).
Tuttavia, dato che l'obiettivo è quello di avere "un oggetto che pulisce dopo essersi all'uscita o un'eccezione", l'attuazione da parte @ ~ unutbu è non corretto:
@contextlib.contextmanager
def make_client():
c=Client()
yield c
c.disconnect_from_server()
with make_client() as c:
...
Se un'eccezione viene generato nella parte ...
, disconnect_from_server_
fa non viene chiamato (poiché l'eccezione si propaga attraverso make_client
, non è presente lì, quindi lo interrompe mentre è in attesa allo yield
).
La soluzione è semplice:
@contextlib.contextmanager
def make_client():
c=Client()
try: yield c
finally: c.disconnect_from_server()
In sostanza, la dichiarazione with
consente di quasi dimenticare il buon vecchio try/finally ... tranne quando si scrive i gestori di contesto con contextlib
, e quindi è davvero importante ricordarlo! -)
fonte
2010-08-24 14:33:30
Inoltre, è possibile definire i metodi per ottenere lo stesso risultato: http://docs.python.org/reference/datamodel.html#with-statement-context-managers – carl
@carl: Grazie, l'ho dimenticato, e sarebbe più facile ... – unutbu