Je recommande d'utiliser la withdé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 finallybloc pour éviter une fuite de ressources lorsqu'une exception se produit.
Pour utiliser l' withinstruction, 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 withclause. 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 withinstruction:
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