Ich würde empfehlen, die Python- with
Anweisung zum Verwalten von Ressourcen zu verwenden, die bereinigt werden müssen. Das Problem bei der Verwendung einer expliziten close()
Anweisung besteht darin, dass Sie sich Sorgen machen müssen, dass Personen vergessen, sie überhaupt aufzurufen oder sie in einem finally
Block zu platzieren, um ein Ressourcenleck zu verhindern, wenn eine Ausnahme auftritt.
with
Erstellen Sie eine Klasse mit den folgenden Methoden, um die Anweisung zu verwenden:
def __enter__(self)
def __exit__(self, exc_type, exc_value, traceback)
In Ihrem obigen Beispiel würden Sie verwenden
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)
Wenn dann jemand Ihre Klasse benutzen wollte, würde er Folgendes tun:
with Package() as package_obj:
# use package_obj
Die Variable package_obj ist eine Instanz vom Typ Package (dies ist der von der __enter__
Methode zurückgegebene Wert ). Die __exit__
Methode wird automatisch aufgerufen, unabhängig davon, ob eine Ausnahme auftritt oder nicht.
Sie könnten diesen Ansatz sogar noch einen Schritt weiter gehen. Im obigen Beispiel könnte jemand Package weiterhin mit seinem Konstruktor instanziieren, ohne die with
Klausel zu verwenden. Du willst nicht, dass das passiert. Sie können dies beheben, indem Sie eine PackageResource-Klasse erstellen, die die Methoden __enter__
und definiert __exit__
. Dann würde die Package-Klasse streng innerhalb der __enter__
Methode definiert und zurückgegeben. Auf diese Weise konnte der Aufrufer die Package-Klasse niemals instanziieren, ohne eine with
Anweisung zu verwenden:
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()
Sie würden dies wie folgt verwenden:
with PackageResource() as package_obj:
# use package_obj