Ich würde empfehlen, die Python- withAnweisung 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 finallyBlock zu platzieren, um ein Ressourcenleck zu verhindern, wenn eine Ausnahme auftritt.
withErstellen 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 withKlausel 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 withAnweisung 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