Consiglio di utilizzare la with
dichiarazione di Python per la gestione delle risorse che devono essere ripulite. Il problema con l'uso di un'istruzione esplicita close()
è che devi preoccuparti che le persone dimentichino di chiamarlo o dimentichino di inserirlo in un finally
blocco per evitare una perdita di risorse quando si verifica un'eccezione.
Per utilizzare l' with
istruzione, creare una classe con i seguenti metodi:
def __enter__(self)
def __exit__(self, exc_type, exc_value, traceback)
Nel tuo esempio sopra, useresti
class Package:
def __init__(self):
self.files = []
def __enter__(self):
return self
# ...
def __exit__(self, exc_type, exc_value, traceback):
for file in self.files:
os.unlink(file)
Quindi, quando qualcuno volesse usare la tua classe, farebbe quanto segue:
with Package() as package_obj:
# use package_obj
La variabile package_obj sarà un'istanza di tipo Package (è il valore restituito dal __enter__
metodo). Il suo __exit__
metodo verrà chiamato automaticamente, indipendentemente dal fatto che si verifichi o meno un'eccezione.
Potresti anche prendere questo approccio un ulteriore passo avanti. Nell'esempio sopra, qualcuno potrebbe ancora creare un'istanza di Package usando il suo costruttore senza usare la with
clausola. Non vuoi che ciò accada. È possibile risolvere questo problema creando una classe PackageResource che definisce i metodi __enter__
e __exit__
. Quindi, la classe Package sarebbe definita rigorosamente all'interno del __enter__
metodo e restituita. In questo modo, il chiamante non potrebbe mai creare un'istanza della classe Package senza usare with
un'istruzione:
class PackageResource:
def __enter__(self):
class Package:
...
self.package_obj = Package()
return self.package_obj
def __exit__(self, exc_type, exc_value, traceback):
self.package_obj.cleanup()
Lo useresti come segue:
with PackageResource() as package_obj:
# use package_obj