Je recommande d'utiliser la with
déclaration de Python pour gérer les ressources qui doivent être nettoyées. Le problème avec l'utilisation d'une close()
déclaration explicite est que vous devez vous inquiéter du fait que les gens oublient de l'appeler ou oublient de le placer dans un finally
bloc pour éviter une fuite de ressources lorsqu'une exception se produit.
Pour utiliser l' with
instruction, créez une classe avec les méthodes suivantes:
def __enter__(self)
def __exit__(self, exc_type, exc_value, traceback)
Dans votre exemple ci-dessus, vous utiliseriez
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)
Ensuite, lorsque quelqu'un voulait utiliser votre classe, il procédait comme suit:
with Package() as package_obj:
# use package_obj
La variable package_obj sera une instance de type Package (c'est la valeur retournée par la __enter__
méthode). Sa __exit__
méthode sera automatiquement appelée, qu'une exception se produise ou non.
Vous pourriez même aller plus loin dans cette approche. Dans l'exemple ci-dessus, quelqu'un pourrait toujours instancier Package en utilisant son constructeur sans utiliser la with
clause. Vous ne voulez pas que cela se produise. Vous pouvez résoudre ce problème en créant une classe PackageResource qui définit les méthodes __enter__
et __exit__
. Ensuite, la classe Package serait définie strictement à l'intérieur de la __enter__
méthode et renvoyée. De cette façon, l'appelant n'a jamais pu instancier la classe Package sans utiliser une with
instruction:
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()
Vous utiliseriez ceci comme suit:
with PackageResource() as package_obj:
# use package_obj