Eu recomendo usar a withdeclaração do Python para gerenciar recursos que precisam ser limpos. O problema com o uso de uma close()declaração explícita é que você precisa se preocupar com as pessoas que se esquecem de chamá-la ou se esquecem de colocá-la em um finallybloco para evitar que um recurso vaze quando ocorrer uma exceção.
Para usar a withinstrução, crie uma classe com os seguintes métodos:
def __enter__(self)
def __exit__(self, exc_type, exc_value, traceback)
No seu exemplo acima, você usaria
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)
Então, quando alguém quisesse usar sua classe, faria o seguinte:
with Package() as package_obj:
# use package_obj
A variável package_obj será uma instância do tipo Package (é o valor retornado pelo __enter__método). Seu __exit__método será chamado automaticamente, independentemente de ocorrer ou não uma exceção.
Você pode até levar essa abordagem um passo adiante. No exemplo acima, alguém ainda pode instanciar o Package usando seu construtor sem usar a withcláusula Você não quer que isso aconteça. Você pode corrigir isso criando uma classe PackageResource que define o __enter__e __exit__métodos. Em seguida, a classe Package seria definida estritamente dentro do __enter__método e retornada. Dessa forma, o chamador nunca poderia instanciar a classe Package sem usar uma withinstrução:
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()
Você usaria isso da seguinte maneira:
with PackageResource() as package_obj:
# use package_obj